Copy rpc error codes from dds to vm_service

Bug: https://github.com/dart-lang/sdk/issues/52636
Change-Id: Icdf66a3499562a2aba50e7f27879497a7b34ab98
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307970
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Elliott Brooks <elliottbrooks@google.com>
This commit is contained in:
Elliott Brooks
2023-06-09 18:13:18 +00:00
committed by Commit Queue
parent db143df804
commit 66ded0cdd9
6 changed files with 300 additions and 43 deletions
+1
View File
@@ -2,6 +2,7 @@
- Update to version `4.7` of the spec.
- Add deprecation notice to `Stack.awaiterFrames`.
- Add deprecation notice to `FrameKind.kAsyncActivation`.
- Expose RPC error codes that were defined in `package:dds`.
## 11.5.0
- Update to version `4.6` of the spec.
+141 -17
View File
@@ -1490,8 +1490,8 @@ class VmServerConnection {
}
final method = request['method'] as String?;
if (method == null) {
throw RPCError(
null, RPCError.kInvalidRequest, 'Invalid Request', request);
throw RPCError(null, RPCErrorKind.kInvalidRequest.code,
'Invalid Request', request);
}
final params = request['params'] as Map<String, dynamic>?;
late Response response;
@@ -1888,8 +1888,8 @@ class VmServerConnection {
response = await _serviceImplementation.callServiceExtension(method,
isolateId: isolateId, args: args);
} else {
throw RPCError(
method, RPCError.kMethodNotFound, 'Method not found', request);
throw RPCError(method, RPCErrorKind.kMethodNotFound.code,
'Method not found', request);
}
}
_responseSink.add({
@@ -1907,7 +1907,7 @@ class VmServerConnection {
final error = e is RPCError
? e.toMap()
: {
'code': RPCError.kInternalError,
'code': RPCErrorKind.kInternalError.code,
'message': '${request['method']}: $e',
'data': {'details': '$st'},
};
@@ -2474,7 +2474,7 @@ class VmService implements VmServiceInterface {
_outstandingRequests.forEach((id, request) {
request._completer.completeError(RPCError(
request.method,
RPCError.kServerError,
RPCErrorKind.kServerError.code,
'Service connection disposed',
));
});
@@ -2615,8 +2615,8 @@ class VmService implements VmServiceInterface {
Future<Map> _routeRequest(String method, Map<String, dynamic> params) async {
final service = _services[method];
if (service == null) {
RPCError error = RPCError(
method, RPCError.kMethodNotFound, 'method not found \'$method\'');
RPCError error = RPCError(method, RPCErrorKind.kMethodNotFound.code,
'method not found \'$method\'');
return {'error': error.toMap()};
}
@@ -2625,7 +2625,7 @@ class VmService implements VmServiceInterface {
} catch (e, st) {
RPCError error = RPCError.withDetails(
method,
RPCError.kServerError,
RPCErrorKind.kServerError.code,
'$e',
details: '$st',
);
@@ -2636,21 +2636,143 @@ class VmService implements VmServiceInterface {
typedef DisposeHandler = Future Function();
class RPCError implements Exception {
/// Application specific error codes.
static const int kServerError = -32000;
// These error codes must be kept in sync with those in vm/json_stream.h and
// vmservice.dart.
enum RPCErrorKind {
/// Application specific error code.
kServerError,
/// The JSON sent is not a valid Request object.
static const int kInvalidRequest = -32600;
kInvalidRequest,
/// The method does not exist or is not available.
static const int kMethodNotFound = -32601;
kMethodNotFound,
/// Invalid method parameter(s), such as a mismatched type.
static const int kInvalidParams = -32602;
kInvalidParams,
/// Internal JSON-RPC error.
static const int kInternalError = -32603;
kInternalError,
/// The requested feature is disabled.
kFeatureDisabled,
/// The stream has already been subscribed to.
kStreamAlreadySubscribed,
/// The stream has not been subscribed to.
kStreamNotSubscribed,
/// Isolate must first be paused.
kIsolateMustBePaused,
/// The service has already been registered.
kServiceAlreadyRegistered,
/// The service no longer exists.
kServiceDisappeared,
/// There was an error in the expression compiler.
kExpressionCompilationError,
/// The custom stream does not exist.
kCustomStreamDoesNotExist,
/// The core stream is not allowed.
kCoreStreamNotAllowed;
static final _codeToErrorMap =
RPCErrorKind.values.fold(<int, RPCErrorKind>{}, (map, error) {
map[error.code] = error;
return map;
});
static RPCErrorKind? fromCode(int code) {
return _codeToErrorMap[code];
}
String get message {
switch (this) {
case kServerError:
return 'Application error';
case kInvalidRequest:
return 'Invalid request object';
case kMethodNotFound:
return 'Method not found';
case kInvalidParams:
return 'Invalid method parameters';
case kInternalError:
return 'Internal JSON-RPC error';
case kFeatureDisabled:
return 'Feature is disabled';
case kStreamAlreadySubscribed:
return 'Stream already subscribed';
case kStreamNotSubscribed:
return 'Stream not subscribed';
case kIsolateMustBePaused:
return 'Isolate must be paused';
case kServiceAlreadyRegistered:
return 'Service already registered';
case kServiceDisappeared:
return 'Service has disappeared';
case kExpressionCompilationError:
return 'Expression compilation error';
case kCustomStreamDoesNotExist:
return 'Custom stream does not exist';
case kCoreStreamNotAllowed:
return 'Core streams are not allowed';
}
}
int get code {
switch (this) {
case kServerError:
return -32000;
case kInvalidRequest:
return -32600;
case kMethodNotFound:
return -32601;
case kInvalidParams:
return -32602;
case kInternalError:
return -32603;
case kFeatureDisabled:
return 100;
case kStreamAlreadySubscribed:
return 103;
case kStreamNotSubscribed:
return 104;
case kIsolateMustBePaused:
return 106;
case kServiceAlreadyRegistered:
return 111;
case kServiceDisappeared:
return 112;
case kExpressionCompilationError:
return 113;
case kCustomStreamDoesNotExist:
return 130;
case kCoreStreamNotAllowed:
return 131;
}
}
}
class RPCError implements Exception {
@Deprecated('Use RPCErrorKind.kServerError.code instead.')
static int get kServerError => RPCErrorKind.kServerError.code;
@Deprecated('Use RPCErrorKind.kInvalidRequest.code instead.')
static int get kInvalidRequest => RPCErrorKind.kInvalidRequest.code;
@Deprecated('Use RPCErrorKind.kMethodNotFound.code instead.')
static int get kMethodNotFound => RPCErrorKind.kMethodNotFound.code;
@Deprecated('Use RPCErrorKind.kInvalidParams.code instead.')
static int get kInvalidParams => RPCErrorKind.kInvalidParams.code;
@Deprecated('Use RPCErrorKind.kInternalError.code instead.')
static int get kInternalError => RPCErrorKind.kInternalError.code;
static RPCError parse(String callingMethod, dynamic json) {
return RPCError(callingMethod, json['code'], json['message'], json['data']);
@@ -2661,7 +2783,9 @@ class RPCError implements Exception {
final String message;
final Map? data;
RPCError(this.callingMethod, this.code, this.message, [this.data]);
RPCError(this.callingMethod, this.code, [message, this.data])
: message =
message ?? RPCErrorKind.fromCode(code)?.message ?? 'Unknown error';
RPCError.withDetails(this.callingMethod, this.code, this.message,
{Object? details})
@@ -150,7 +150,7 @@ var tests = <IsolateTest>[
expect(false, isTrue, reason: 'Unreachable');
} on RPCError catch (e) {
caughtException = true;
expect(e.code, RPCError.kInvalidParams);
expect(e.code, RPCErrorKind.kInvalidParams.code);
expect(e.details, "addBreakpoint: invalid 'column' parameter: 0");
}
expect(caughtException, isTrue);
@@ -37,7 +37,7 @@ var tests = <VMTest>[
expect(false, isTrue, reason: 'Unreachable');
} on RPCError catch (e) {
caughtException = true;
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
expect(e.details, "getIsolate: invalid 'isolateId' parameter: badid");
}
expect(caughtException, isTrue);
+8 -8
View File
@@ -766,7 +766,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got library with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
expect(e.message, "Invalid params");
}
},
@@ -802,7 +802,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got script with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
expect(e.message, "Invalid params");
}
},
@@ -1220,7 +1220,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got class with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
expect(e.message, "Invalid params");
}
},
@@ -1253,7 +1253,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got type with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
expect(e.message, "Invalid params");
}
},
@@ -1394,7 +1394,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got function with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
expect(e.message, "Invalid params");
}
},
@@ -1494,7 +1494,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got field initializer with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
}
},
@@ -1538,7 +1538,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got field with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
}
},
@@ -1587,7 +1587,7 @@ var tests = <IsolateTest>[
await service.getObject(isolateId, objectId);
fail('successfully got code with bad ID');
} on RPCError catch (e) {
expect(e.code, equals(RPCError.kInvalidParams));
expect(e.code, equals(RPCErrorKind.kInvalidParams.code));
expect(e.message, "Invalid params");
}
},
+148 -16
View File
@@ -104,7 +104,10 @@ final String _implCode = r'''
await _streamSub.cancel();
_outstandingRequests.forEach((id, request) {
request._completer.completeError(RPCError(
request.method, RPCError.kServerError, 'Service connection disposed',));
request.method,
RPCErrorKind.kServerError.code,
'Service connection disposed',
));
});
_outstandingRequests.clear();
if (_disposeHandler != null) {
@@ -237,8 +240,8 @@ final String _implCode = r'''
Future<Map> _routeRequest(String method, Map<String, dynamic> params) async{
final service = _services[method];
if (service == null) {
RPCError error = RPCError(
method, RPCError.kMethodNotFound, 'method not found \'$method\'');
RPCError error = RPCError(method, RPCErrorKind.kMethodNotFound.code,
'method not found \'$method\'');
return {'error': error.toMap()};
}
@@ -246,7 +249,11 @@ final String _implCode = r'''
return await service(params);
} catch (e, st) {
RPCError error = RPCError.withDetails(
method, RPCError.kServerError, '$e', details: '$st',);
method,
RPCErrorKind.kServerError.code,
'$e',
details: '$st',
);
return {'error': error.toMap()};
}
}
@@ -257,21 +264,143 @@ final String _rpcError = r'''
typedef DisposeHandler = Future Function();
class RPCError implements Exception {
/// Application specific error codes.
static const int kServerError = -32000;
// These error codes must be kept in sync with those in vm/json_stream.h and
// vmservice.dart.
enum RPCErrorKind {
/// Application specific error code.
kServerError,
/// The JSON sent is not a valid Request object.
static const int kInvalidRequest = -32600;
kInvalidRequest,
/// The method does not exist or is not available.
static const int kMethodNotFound = -32601;
kMethodNotFound,
/// Invalid method parameter(s), such as a mismatched type.
static const int kInvalidParams = -32602;
kInvalidParams,
/// Internal JSON-RPC error.
static const int kInternalError = -32603;
kInternalError,
/// The requested feature is disabled.
kFeatureDisabled,
/// The stream has already been subscribed to.
kStreamAlreadySubscribed,
/// The stream has not been subscribed to.
kStreamNotSubscribed,
/// Isolate must first be paused.
kIsolateMustBePaused,
/// The service has already been registered.
kServiceAlreadyRegistered,
/// The service no longer exists.
kServiceDisappeared,
/// There was an error in the expression compiler.
kExpressionCompilationError,
/// The custom stream does not exist.
kCustomStreamDoesNotExist,
/// The core stream is not allowed.
kCoreStreamNotAllowed;
static final _codeToErrorMap =
RPCErrorKind.values.fold(<int, RPCErrorKind>{}, (map, error) {
map[error.code] = error;
return map;
});
static RPCErrorKind? fromCode(int code) {
return _codeToErrorMap[code];
}
String get message {
switch (this) {
case kServerError:
return 'Application error';
case kInvalidRequest:
return 'Invalid request object';
case kMethodNotFound:
return 'Method not found';
case kInvalidParams:
return 'Invalid method parameters';
case kInternalError:
return 'Internal JSON-RPC error';
case kFeatureDisabled:
return 'Feature is disabled';
case kStreamAlreadySubscribed:
return 'Stream already subscribed';
case kStreamNotSubscribed:
return 'Stream not subscribed';
case kIsolateMustBePaused:
return 'Isolate must be paused';
case kServiceAlreadyRegistered:
return 'Service already registered';
case kServiceDisappeared:
return 'Service has disappeared';
case kExpressionCompilationError:
return 'Expression compilation error';
case kCustomStreamDoesNotExist:
return 'Custom stream does not exist';
case kCoreStreamNotAllowed:
return 'Core streams are not allowed';
}
}
int get code {
switch (this) {
case kServerError:
return -32000;
case kInvalidRequest:
return -32600;
case kMethodNotFound:
return -32601;
case kInvalidParams:
return -32602;
case kInternalError:
return -32603;
case kFeatureDisabled:
return 100;
case kStreamAlreadySubscribed:
return 103;
case kStreamNotSubscribed:
return 104;
case kIsolateMustBePaused:
return 106;
case kServiceAlreadyRegistered:
return 111;
case kServiceDisappeared:
return 112;
case kExpressionCompilationError:
return 113;
case kCustomStreamDoesNotExist:
return 130;
case kCoreStreamNotAllowed:
return 131;
}
}
}
class RPCError implements Exception {
@Deprecated('Use RPCErrorKind.kServerError.code instead.')
static int get kServerError => RPCErrorKind.kServerError.code;
@Deprecated('Use RPCErrorKind.kInvalidRequest.code instead.')
static int get kInvalidRequest => RPCErrorKind.kInvalidRequest.code;
@Deprecated('Use RPCErrorKind.kMethodNotFound.code instead.')
static int get kMethodNotFound => RPCErrorKind.kMethodNotFound.code;
@Deprecated('Use RPCErrorKind.kInvalidParams.code instead.')
static int get kInvalidParams => RPCErrorKind.kInvalidParams.code;
@Deprecated('Use RPCErrorKind.kInternalError.code instead.')
static int get kInternalError => RPCErrorKind.kInternalError.code;
static RPCError parse(String callingMethod, dynamic json) {
return RPCError(callingMethod, json['code'], json['message'], json['data']);
@@ -282,7 +411,9 @@ class RPCError implements Exception {
final String message;
final Map? data;
RPCError(this.callingMethod, this.code, this.message, [this.data]);
RPCError(this.callingMethod, this.code, [message, this.data])
: message =
message ?? RPCErrorKind.fromCode(code)?.message ?? 'Unknown error';
RPCError.withDetails(this.callingMethod, this.code, this.message,
{Object? details})
@@ -710,8 +841,8 @@ class VmServerConnection {
}
final method = request['method'] as String?;
if (method == null) {
throw RPCError(
null, RPCError.kInvalidRequest, 'Invalid Request', request);
throw RPCError(null, RPCErrorKind.kInvalidRequest.code,
'Invalid Request', request);
}
final params = request['params'] as Map<String, dynamic>?;
late Response response;
@@ -789,7 +920,8 @@ class VmServerConnection {
response = await _serviceImplementation.callServiceExtension(method,
isolateId: isolateId, args: args);
} else {
throw RPCError(method, RPCError.kMethodNotFound, 'Method not found', request);
throw RPCError(method, RPCErrorKind.kMethodNotFound.code,
'Method not found', request);
}
''');
// Terminate the switch
@@ -815,7 +947,7 @@ class VmServerConnection {
final error = e is RPCError
? e.toMap()
: {
'code': RPCError.kInternalError,
'code': RPCErrorKind.kInternalError.code,
'message': '${request['method']}: $e',
'data': {'details': '$st'},
};