Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ class PropertyEditorSidebar {
/// Analytics id to track events that come from the DTD editor sidebar.
static String get id => 'propertyEditorSidebar';

/// Identifier for errors returned from the getEditableArguments API.
static String get getEditableArgumentsIdentifier =>
'${id}Error-getEditableArguments';

/// Identifier for errors returned from the editArgument API.
static String get editArgumentIdentifier => '${id}Error-editArgument';

/// Analytics event that is sent when the property editor is updated with new
/// properties.
static String widgetPropertiesUpdate({String? name}) =>
Expand Down
10 changes: 10 additions & 0 deletions packages/devtools_app/lib/src/shared/editor/api_classes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ abstract class Field {
static const vmServiceUri = 'vmServiceUri';
}

/// Multi-purpose errors used by the Analysis Server.
enum AnalysisServerError {
/// The document content was modified before the request was completed.
contentModifiedError(code: -32801);

const AnalysisServerError({required this.code});

final int code;
}

/// A base class for all known events that an editor can produce.
///
/// The set of subclasses is not guaranteed to match actual events from any
Expand Down
66 changes: 47 additions & 19 deletions packages/devtools_app/lib/src/shared/editor/editor_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import 'package:devtools_app_shared/utils.dart';
import 'package:dtd/dtd.dart';
import 'package:flutter/foundation.dart';
import 'package:json_rpc_2/json_rpc_2.dart';
import 'package:logging/logging.dart';

import '../analytics/constants.dart';
import '../framework/app_error_handling.dart';
import 'api_classes.dart';

final _log = Logger('editor_client');

/// A client wrapper that connects to an editor over DTD.
///
/// Changes made to the editor services/events should be considered carefully to
Expand Down Expand Up @@ -262,18 +260,40 @@ class EditorClient extends DisposableController
}) async {
final method = editableArgumentsMethodName.value;
if (method == null) return null;
final response = await _callLspApi(
method,
params: {
'type': 'Object', // This is required by DTD.
'textDocument': textDocument.toJson(),
'position': position.toJson(),
},
);
final result = response.result[Field.result];
return result != null
? EditableArgumentsResult.fromJson(result as Map<String, Object?>)
: null;
try {
final response = await _callLspApi(
method,
params: {
'type': 'Object', // This is required by DTD.
'textDocument': textDocument.toJson(),
'position': position.toJson(),
},
);
final result = response.result[Field.result];
return result != null
? EditableArgumentsResult.fromJson(result as Map<String, Object?>)
: null;
} on RpcException catch (e, st) {
// We expect content modified errors if a user edits their code before the
// request completes. Therefore it is safe to ignore.
if (e.code != AnalysisServerError.contentModifiedError.code) {
final errorMessage = e.message;
reportError(
errorMessage,
errorType: PropertyEditorSidebar.getEditableArgumentsIdentifier,
stack: st,
);
}
return null;
} catch (e, st) {
final errorMessage = 'Unknown error: $e';
reportError(
errorMessage,
errorType: PropertyEditorSidebar.getEditableArgumentsIdentifier,
stack: st,
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we could reduce duplication by putting this in a finally clause. If we had a variable String? errorMessage defined before the try, the on RpcException and catch blocks could just set the errorMessage variable that is used in the finally block that calls reportError

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

return null;
}
}

/// Requests that the Analysis Server makes a code edit for an argument.
Expand Down Expand Up @@ -301,17 +321,25 @@ class EditorClient extends DisposableController
},
);
return EditArgumentResponse(success: true);
} on RpcException catch (e) {
} on RpcException catch (e, st) {
final errorMessage = e.message;
_log.severe(errorMessage);
reportError(
errorMessage,
errorType: PropertyEditorSidebar.editArgumentIdentifier,
stack: st,
);
return EditArgumentResponse(
success: false,
errorCode: e.code,
errorMessage: errorMessage,
);
} catch (e) {
} catch (e, st) {
final errorMessage = 'Unknown error: $e';
_log.severe(errorMessage);
reportError(
errorMessage,
errorType: PropertyEditorSidebar.editArgumentIdentifier,
stack: st,
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put in finally instead

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

return EditArgumentResponse(
success: false,
errorMessage: 'Unknown error: $e',
Expand Down