From e6049a483d358c6ab794b3678293b139cb4c5638 Mon Sep 17 00:00:00 2001 From: Andrew Coutts Date: Mon, 14 Sep 2020 12:51:19 -0400 Subject: [PATCH] Replace StatusCode implementation with auto-generated equivalent from code.proto. Includes status code string name in the error now --- interop/lib/src/client.dart | 16 ++-- lib/grpc.dart | 5 +- lib/src/client/call.dart | 37 ++++---- lib/src/server/handler.dart | 2 +- lib/src/shared/status.dart | 147 +++++------------------------ test/client_tests/client_test.dart | 4 +- test/server_test.dart | 32 +++---- test/src/server_utils.dart | 9 +- test/stream_test.dart | 8 +- test/timeout_test.dart | 2 +- 10 files changed, 75 insertions(+), 187 deletions(-) diff --git a/interop/lib/src/client.dart b/interop/lib/src/client.dart index 2cb93c87..6109ccb5 100644 --- a/interop/lib/src/client.dart +++ b/interop/lib/src/client.dart @@ -22,6 +22,7 @@ import 'package:grpc/grpc.dart'; import 'generated/empty.pb.dart'; import 'generated/messages.pb.dart'; import 'generated/test.pbgrpc.dart'; +import 'package:grpc/src/generated/google/rpc/code.pbenum.dart'; const _headerEchoKey = 'x-grpc-test-echo-initial'; const _headerEchoData = 'test_initial_metadata_value'; @@ -1000,9 +1001,10 @@ class Tester { /// * received status message is the same as the sent message for both /// Procedure steps 1 and 2 Future statusCodeAndMessage() async { - final expectedStatus = GrpcError.custom(2, 'test status message'); + final expectedStatus = + GrpcError.custom(Code.UNKNOWN, 'test status message'); final responseStatus = EchoStatus() - ..code = expectedStatus.code + ..code = expectedStatus.code.value ..message = expectedStatus.message; try { await client.unaryCall(SimpleRequest()..responseStatus = responseStatus); @@ -1044,7 +1046,7 @@ class Tester { await client.unimplementedCall(Empty()); throw 'Did not throw.'; } on GrpcError catch (e) { - if (e.code != StatusCode.unimplemented) { + if (e.code != Code.UNIMPLEMENTED) { throw 'Unexpected status code ${e.code} - ${e.message}.'; } } @@ -1064,7 +1066,7 @@ class Tester { await unimplementedServiceClient.unimplementedCall(Empty()); throw 'Did not throw.'; } on GrpcError catch (e) { - if (e.code != StatusCode.unimplemented) { + if (e.code != Code.UNIMPLEMENTED) { throw 'Unexpected status code ${e.code} - ${e.message}.'; } } @@ -1087,7 +1089,7 @@ class Tester { await call; throw 'Expected exception.'; } on GrpcError catch (e) { - if (e.code != StatusCode.cancelled) { + if (e.code != Code.CANCELLED) { throw 'Unexpected status code ${e.code} - ${e.message}'; } } @@ -1131,7 +1133,7 @@ class Tester { call.cancel(); }, onError: (e) { if (e is! GrpcError) completer.completeError('Unexpected error: $e.'); - if (e.code != StatusCode.cancelled) { + if (e.code != Code.CANCELLED) { completer .completeError('Unexpected status code ${e.code}: ${e.message}.'); } @@ -1175,7 +1177,7 @@ class Tester { } throw 'Expected exception.'; } on GrpcError catch (e) { - if (e.code != StatusCode.deadlineExceeded) { + if (e.code != Code.DEADLINE_EXCEEDED) { throw 'Unexpected status code ${e.code} - ${e.message}.'; } } finally { diff --git a/lib/grpc.dart b/lib/grpc.dart index 08731082..b3ea35b3 100644 --- a/lib/grpc.dart +++ b/lib/grpc.dart @@ -37,8 +37,7 @@ export 'src/client/options.dart' ChannelOptions; export 'src/client/transport/http2_credentials.dart' show BadCertificateHandler, allowBadCertificates, ChannelCredentials; - -/// Status detail types +export 'src/generated/google/rpc/code.pb.dart'; export 'src/generated/google/rpc/error_details.pb.dart'; export 'src/server/call.dart' show ServiceCall; export 'src/server/interceptor.dart' show Interceptor; @@ -48,6 +47,6 @@ export 'src/shared/message.dart' show GrpcMessage, GrpcMetadata, GrpcData, grpcDecompressor; export 'src/shared/security.dart' show supportedAlpnProtocols, createSecurityContext; -export 'src/shared/status.dart' show StatusCode, GrpcError; +export 'src/shared/status.dart' show GrpcError; export 'src/shared/streams.dart' show GrpcHttpEncoder, GrpcHttpDecoder; export 'src/shared/timeout.dart' show toTimeoutString, fromTimeoutString; diff --git a/lib/src/client/call.dart b/lib/src/client/call.dart index 283d7c14..a10e182a 100644 --- a/lib/src/client/call.dart +++ b/lib/src/client/call.dart @@ -16,8 +16,8 @@ import 'dart:async'; import 'dart:convert'; +import 'package:grpc/src/generated/google/rpc/code.pbenum.dart'; import 'package:grpc/src/generated/google/rpc/status.pb.dart'; -import 'package:protobuf/protobuf.dart'; import '../shared/message.dart'; import '../shared/status.dart'; @@ -244,15 +244,14 @@ class ClientCall implements Response { _trailers.complete(metadata); // TODO(jakobr): Parse more! if (metadata.containsKey('grpc-status')) { - final status = int.parse(metadata['grpc-status']); - final message = metadata['grpc-message'] == null - ? null - : Uri.decodeFull(metadata['grpc-message']); - if (status != 0) { + final details = + _parseStatusDetails(metadata['grpc-status-details-bin']); + final statusCode = details.code; + if (statusCode != 0) { _responseError(GrpcError.custom( - status, - message, - _decodeStatusDetails(metadata['grpc-status-details-bin']), + Code.values[statusCode], + details.message, + details.details.map((e) => parseGeneratedMessage(e)).toList(), )); } } @@ -288,18 +287,14 @@ class ClientCall implements Response { // Only received a header frame and no data frames, so the header // should contain "trailers" as well (Trailers-Only). _trailers.complete(_headerMetadata); - final status = _headerMetadata['grpc-status']; - // If status code is missing, we must treat it as '0'. As in 'success'. - final statusCode = status != null ? int.parse(status) : 0; - + final details = + _parseStatusDetails(_headerMetadata['grpc-status-details-bin']); + final statusCode = details.code; if (statusCode != 0) { - final message = _headerMetadata['grpc-message'] == null - ? null - : Uri.decodeFull(_headerMetadata['grpc-message']); _responseError(GrpcError.custom( - statusCode, - message, - _decodeStatusDetails(_headerMetadata['grpc-status-details-bin']), + Code.values[statusCode], + details.message, + details.details.map((e) => parseGeneratedMessage(e)).toList(), )); } } @@ -365,7 +360,7 @@ class ClientCall implements Response { } } -List _decodeStatusDetails(String data) { +Status _parseStatusDetails(String data) { /// Parse details out of message. Length must be an even multiple of 4 so we pad it if needed. var details = data ?? ''; while (details.length % 4 != 0) { @@ -374,5 +369,5 @@ List _decodeStatusDetails(String data) { /// Parse each Any type into the correct GeneratedMessage final parsedStatus = Status.fromBuffer(base64Url.decode(details)); - return parsedStatus.details.map((e) => parseGeneratedMessage(e)).toList(); + return parsedStatus; } diff --git a/lib/src/server/handler.dart b/lib/src/server/handler.dart index 0d27f7a9..c41b2635 100644 --- a/lib/src/server/handler.dart +++ b/lib/src/server/handler.dart @@ -349,7 +349,7 @@ class ServerHandler_ extends ServiceCall { } void _sendError(GrpcError error) { - sendTrailers(status: error.code, message: error.message); + sendTrailers(status: error.code.value, message: error.message); } void cancel() { diff --git a/lib/src/shared/status.dart b/lib/src/shared/status.dart index 0b3ac0a3..5fa6b3d9 100644 --- a/lib/src/shared/status.dart +++ b/lib/src/shared/status.dart @@ -14,115 +14,12 @@ // limitations under the License. import 'package:grpc/src/generated/google/protobuf/any.pb.dart'; +import 'package:grpc/src/generated/google/rpc/code.pbenum.dart'; import 'package:grpc/src/generated/google/rpc/error_details.pb.dart'; import 'package:protobuf/protobuf.dart'; -class StatusCode { - /// The operation completed successfully. - static const ok = 0; - - /// The operation was cancelled (typically by the caller). - static const cancelled = 1; - - /// Unknown error. An example of where this error may be returned is if a - /// Status value received from another address space belongs to an error-space - /// that is not known in this address space. Also errors raised by APIs that - /// do not return enough error information may be converted to this error. - static const unknown = 2; - - /// Client specified an invalid argument. Note that this differs from - /// [failedPrecondition]. [invalidArgument] indicates arguments that are - /// problematic regardless of the state of the system (e.g., a malformed file - /// name). - static const invalidArgument = 3; - - /// Deadline expired before operation could complete. For operations that - /// change the state of the system, this error may be returned even if the - /// operation has completed successfully. For example, a successful response - /// from a server could have been delayed long enough for the deadline to - /// expire. - static const deadlineExceeded = 4; - - /// Some requested entity (e.g., file or directory) was not found. - static const notFound = 5; - - /// Some entity that we attempted to create (e.g., file or directory) already - /// exists. - static const alreadyExists = 6; - - /// The caller does not have permission to execute the specified operation. - /// [permissionDenied] must not be used for rejections caused by exhausting - /// some resource (use [resourceExhausted] instead for those errors). - /// [permissionDenied] must not be used if the caller cannot be identified - /// (use [unauthenticated] instead for those errors). - static const permissionDenied = 7; - - /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the - /// entire file system is out of space. - static const resourceExhausted = 8; - - /// Operation was rejected because the system is not in a state required for - /// the operation's execution. For example, directory to be deleted may be - /// non-empty, an rmdir operation is applied to a non-directory, etc. - /// - /// A litmus test that may help a service implementor in deciding between - /// [failedPrecondition], [aborted], and [unavailable]: - /// (a) Use [unavailable] if the client can retry just the failing call. - /// (b) Use [aborted] if the client should retry at a higher-level (e.g., - /// restarting a read-modify-write sequence). - /// (c) Use [failedPrecondition] if the client should not retry until the - /// system state has been explicitly fixed. E.g., if an "rmdir" fails - /// because the directory is non-empty, [failedPrecondition] should be - /// returned since the client should not retry unless they have first - /// fixed up the directory by deleting files from it. - static const failedPrecondition = 9; - - /// The operation was aborted, typically due to a concurrency issue like - /// sequencer check failures, transaction aborts, etc. - /// - /// See litmus test above for deciding between [failedPrecondition], - /// [aborted], and [unavailable]. - static const aborted = 10; - - /// Operation was attempted past the valid range. E.g., seeking or reading - /// past end of file. - /// - /// Unlike invalidArgument, this error indicates a problem that may be fixed - /// if the system state changes. For example, a 32-bit file system will - /// generate invalidArgument if asked to read at an offset that is not in the - /// range [0,2^32-1], but it will generate [outOfRange] if asked to read from - /// an offset past the current file size. - /// - /// There is a fair bit of overlap between [failedPrecondition] and - /// [outOfRange]. We recommend using [outOfRange] (the more specific error) - /// when it applies so that callers who are iterating through a space can - /// easily look for an [outOfRange] error to detect when they are done. - static const outOfRange = 11; - - /// Operation is not implemented or not supported/enabled in this service. - static const unimplemented = 12; - - /// Internal errors. Means some invariants expected by underlying system has - /// been broken. If you see one of these errors, something is very broken. - static const internal = 13; - - /// The service is currently unavailable. This is a most likely a transient - /// condition and may be corrected by retrying with a backoff. - /// - /// See litmus test above for deciding between [failedPrecondition], - /// [aborted], and [unavailable]. - static const unavailable = 14; - - /// Unrecoverable data loss or corruption. - static const dataLoss = 15; - - /// The request does not have valid authentication credentials for the - /// operation. - static const unauthenticated = 16; -} - class GrpcError implements Exception { - final int code; + final Code code; final String message; final List details; @@ -130,24 +27,23 @@ class GrpcError implements Exception { GrpcError.custom(this.code, [this.message, this.details]); /// The operation completed successfully. - GrpcError.ok([this.message, this.details]) : code = StatusCode.ok; + GrpcError.ok([this.message, this.details]) : code = Code.OK; /// The operation was cancelled (typically by the caller). - GrpcError.cancelled([this.message, this.details]) - : code = StatusCode.cancelled; + GrpcError.cancelled([this.message, this.details]) : code = Code.CANCELLED; /// Unknown error. An example of where this error may be returned is if a /// Status value received from another address space belongs to an error-space /// that is not known in this address space. Also errors raised by APIs that /// do not return enough error information may be converted to this error. - GrpcError.unknown([this.message, this.details]) : code = StatusCode.unknown; + GrpcError.unknown([this.message, this.details]) : code = Code.UNKNOWN; /// Client specified an invalid argument. Note that this differs from /// [failedPrecondition]. [invalidArgument] indicates arguments that are /// problematic regardless of the state of the system (e.g., a malformed file /// name). GrpcError.invalidArgument([this.message, this.details]) - : code = StatusCode.invalidArgument; + : code = Code.INVALID_ARGUMENT; /// Deadline expired before operation could complete. For operations that /// change the state of the system, this error may be returned even if the @@ -155,15 +51,15 @@ class GrpcError implements Exception { /// from a server could have been delayed long enough for the deadline to /// expire. GrpcError.deadlineExceeded([this.message, this.details]) - : code = StatusCode.deadlineExceeded; + : code = Code.DEADLINE_EXCEEDED; /// Some requested entity (e.g., file or directory) was not found. - GrpcError.notFound([this.message, this.details]) : code = StatusCode.notFound; + GrpcError.notFound([this.message, this.details]) : code = Code.NOT_FOUND; /// Some entity that we attempted to create (e.g., file or directory) already /// exists. GrpcError.alreadyExists([this.message, this.details]) - : code = StatusCode.alreadyExists; + : code = Code.ALREADY_EXISTS; /// The caller does not have permission to execute the specified operation. /// [permissionDenied] must not be used for rejections caused by exhausting @@ -171,12 +67,12 @@ class GrpcError implements Exception { /// [permissionDenied] must not be used if the caller cannot be identified /// (use [unauthenticated] instead for those errors). GrpcError.permissionDenied([this.message, this.details]) - : code = StatusCode.permissionDenied; + : code = Code.PERMISSION_DENIED; /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the /// entire file system is out of space. GrpcError.resourceExhausted([this.message, this.details]) - : code = StatusCode.resourceExhausted; + : code = Code.RESOURCE_EXHAUSTED; /// Operation was rejected because the system is not in a state required for /// the operation's execution. For example, directory to be deleted may be @@ -193,14 +89,14 @@ class GrpcError implements Exception { /// returned since the client should not retry unless they have first /// fixed up the directory by deleting files from it. GrpcError.failedPrecondition([this.message, this.details]) - : code = StatusCode.failedPrecondition; + : code = Code.FAILED_PRECONDITION; /// The operation was aborted, typically due to a concurrency issue like /// sequencer check failures, transaction aborts, etc. /// /// See litmus test above for deciding between [failedPrecondition], /// [aborted], and [unavailable]. - GrpcError.aborted([this.message, this.details]) : code = StatusCode.aborted; + GrpcError.aborted([this.message, this.details]) : code = Code.ABORTED; /// Operation was attempted past the valid range. E.g., seeking or reading /// past end of file. @@ -215,33 +111,31 @@ class GrpcError implements Exception { /// [outOfRange]. We recommend using [outOfRange] (the more specific error) /// when it applies so that callers who are iterating through a space can /// easily look for an [outOfRange] error to detect when they are done. - GrpcError.outOfRange([this.message, this.details]) - : code = StatusCode.outOfRange; + GrpcError.outOfRange([this.message, this.details]) : code = Code.OUT_OF_RANGE; /// Operation is not implemented or not supported/enabled in this service. GrpcError.unimplemented([this.message, this.details]) - : code = StatusCode.unimplemented; + : code = Code.UNIMPLEMENTED; /// Internal errors. Means some invariants expected by underlying system has /// been broken. If you see one of these errors, something is very broken. // TODO(sigurdm): This should probably not be an [Exception]. - GrpcError.internal([this.message, this.details]) : code = StatusCode.internal; + GrpcError.internal([this.message, this.details]) : code = Code.INTERNAL; /// The service is currently unavailable. This is a most likely a transient /// condition and may be corrected by retrying with a backoff. /// /// See litmus test above for deciding between [failedPrecondition], /// [aborted], and [unavailable]. - GrpcError.unavailable([this.message, this.details]) - : code = StatusCode.unavailable; + GrpcError.unavailable([this.message, this.details]) : code = Code.UNAVAILABLE; /// Unrecoverable data loss or corruption. - GrpcError.dataLoss([this.message, this.details]) : code = StatusCode.dataLoss; + GrpcError.dataLoss([this.message, this.details]) : code = Code.DATA_LOSS; /// The request does not have valid authentication credentials for the /// operation. GrpcError.unauthenticated([this.message, this.details]) - : code = StatusCode.unauthenticated; + : code = Code.UNAUTHENTICATED; @override bool operator ==(other) { @@ -253,7 +147,8 @@ class GrpcError implements Exception { int get hashCode => code.hashCode ^ (message?.hashCode ?? 17); @override - String toString() => 'gRPC Error ($code, $message, $details)'; + String toString() => + 'gRPC Error (${code.value} ${code.name}, $message, $details)'; } /// Parse error details into the right kind of GeneratedMessage. diff --git a/test/client_tests/client_test.dart b/test/client_tests/client_test.dart index 70480df6..14e1f6a3 100644 --- a/test/client_tests/client_test.dart +++ b/test/client_tests/client_test.dart @@ -238,7 +238,7 @@ void main() { }); test('Call throws if non-zero status is received', () async { - const customStatusCode = 17; + const customStatusCode = Code.UNKNOWN; const customStatusMessage = 'Custom message'; void handleRequest(_) { @@ -258,7 +258,7 @@ void main() { }); test('Call throws decoded message', () async { - const customStatusCode = 17; + const customStatusCode = Code.UNKNOWN; const customStatusMessage = 'エラー'; const encodedCustomStatusMessage = '%E3%82%A8%E3%83%A9%E3%83%BC'; diff --git a/test/server_test.dart b/test/server_test.dart index c9fd0eb0..a13a071c 100644 --- a/test/server_test.dart +++ b/test/server_test.dart @@ -96,22 +96,21 @@ void main() { test('Server returns error on missing call header', () async { harness - ..expectErrorResponse(StatusCode.unimplemented, 'Expected header frame') + ..expectErrorResponse(Code.UNIMPLEMENTED, 'Expected header frame') ..sendData(dummyValue); await harness.fromServer.done; }); test('Server returns error on invalid path', () async { harness - ..expectErrorResponse(StatusCode.unimplemented, 'Invalid path') + ..expectErrorResponse(Code.UNIMPLEMENTED, 'Invalid path') ..sendRequestHeader('InvalidPath'); await harness.fromServer.done; }); test('Server returns error on unimplemented path', () async { harness - ..expectErrorResponse( - StatusCode.unimplemented, 'Path /Test/NotFound not found') + ..expectErrorResponse(Code.UNIMPLEMENTED, 'Path /Test/NotFound not found') ..sendRequestHeader('/Test/NotFound'); await harness.fromServer.done; }); @@ -161,7 +160,7 @@ void main() { harness ..service.unaryHandler = expectError(GrpcError.unimplemented('No request received')) - ..expectErrorResponse(StatusCode.unimplemented, 'No request received') + ..expectErrorResponse(Code.UNIMPLEMENTED, 'No request received') ..sendRequestHeader('/Test/Unary') ..toServer.close(); await harness.fromServer.done; @@ -174,7 +173,7 @@ void main() { harness ..service.unaryHandler = methodHandler - ..expectErrorResponse(StatusCode.unknown, '%E3%82%A8%E3%83%A9%E3%83%BC') + ..expectErrorResponse(Code.UNKNOWN, '%E3%82%A8%E3%83%A9%E3%83%BC') ..sendRequestHeader('/Test/Unary') ..sendData(dummyValue) ..toServer.close(); @@ -186,7 +185,7 @@ void main() { harness ..service.unaryHandler = expectError(GrpcError.unimplemented('Expected request')) - ..expectErrorResponse(StatusCode.unimplemented, 'Expected request') + ..expectErrorResponse(Code.UNIMPLEMENTED, 'Expected request') ..sendRequestHeader('/Test/Unary') ..toServer.add(HeadersStreamMessage([])) ..toServer.close(); @@ -197,7 +196,7 @@ void main() { harness ..service.unaryHandler = expectError(GrpcError.unimplemented('Too many requests')) - ..expectErrorResponse(StatusCode.unimplemented, 'Too many requests') + ..expectErrorResponse(Code.UNIMPLEMENTED, 'Too many requests') ..sendRequestHeader('/Test/Unary') ..sendData(dummyValue) ..sendData(dummyValue) @@ -210,7 +209,7 @@ void main() { ..service.bidirectionalHandler = expectErrorStreaming( GrpcError.internal('Error deserializing request: Failed')) ..expectErrorResponse( - StatusCode.internal, 'Error deserializing request: Failed') + Code.INTERNAL, 'Error deserializing request: Failed') ..sendRequestHeader('/Test/RequestError') ..sendData(dummyValue) ..toServer.close(); @@ -221,8 +220,7 @@ void main() { harness ..service.bidirectionalHandler = expectErrorStreaming( GrpcError.internal('Error sending response: Failed')) - ..expectErrorResponse( - StatusCode.internal, 'Error sending response: Failed') + ..expectErrorResponse(Code.INTERNAL, 'Error sending response: Failed') ..sendRequestHeader('/Test/ResponseError') ..sendData(dummyValue) ..sendData(dummyValue) @@ -239,7 +237,7 @@ void main() { harness ..service.unaryHandler = methodHandler - ..expectTrailingErrorResponse(StatusCode.internal, 'Headers already sent') + ..expectTrailingErrorResponse(Code.INTERNAL, 'Headers already sent') ..sendRequestHeader('/Test/Unary'); await harness.fromServer.done; }); @@ -288,7 +286,7 @@ void main() { () async { harness ..expectErrorResponse( - StatusCode.unavailable, 'Request stream closed unexpectedly') + Code.UNAVAILABLE, 'Request stream closed unexpectedly') ..toServer.close(); await harness.fromServer.done; }); @@ -335,7 +333,7 @@ void main() { harness ..interceptor.handler = handler ..expectErrorResponse( - StatusCode.unauthenticated, 'Request is unauthenticated') + Code.UNAUTHENTICATED, 'Request is unauthenticated') ..sendRequestHeader('/Test/Unary'); await harness.fromServer.done; @@ -354,8 +352,7 @@ void main() { Future doTest(Interceptor handler) async { harness ..interceptor.handler = handler - ..expectErrorResponse( - StatusCode.internal, 'Exception: Reason is unknown') + ..expectErrorResponse(Code.INTERNAL, 'Exception: Reason is unknown') ..sendRequestHeader('/Test/Unary'); await harness.fromServer.done; @@ -375,8 +372,7 @@ void main() { harness ..interceptor.handler = interceptor - ..expectErrorResponse( - StatusCode.internal, 'Exception: Reason is unknown') + ..expectErrorResponse(Code.INTERNAL, 'Exception: Reason is unknown') ..sendRequestHeader('/Test/Unary') ..sendData(1); diff --git a/test/src/server_utils.dart b/test/src/server_utils.dart index eb37a641..81a9b51a 100644 --- a/test/src/server_utils.dart +++ b/test/src/server_utils.dart @@ -156,14 +156,15 @@ class ServerHarness { onDone: expectAsync0(() {}, count: 1)); } - void expectErrorResponse(int status, String message) { - setupTest([errorTrailerValidator(status, message, validateHeader: true)]); + void expectErrorResponse(Code status, String message) { + setupTest( + [errorTrailerValidator(status.value, message, validateHeader: true)]); } - void expectTrailingErrorResponse(int status, String message) { + void expectTrailingErrorResponse(Code status, String message) { setupTest([ headerValidator(), - errorTrailerValidator(status, message, validateHeader: false) + errorTrailerValidator(status.value, message, validateHeader: false) ]); } diff --git a/test/stream_test.dart b/test/stream_test.dart index 5246f9d1..24f87396 100644 --- a/test/stream_test.dart +++ b/test/stream_test.dart @@ -69,7 +69,7 @@ void main() { await result; fail('Did not throw'); } on GrpcError catch (e) { - expect(e.code, StatusCode.unavailable); + expect(e.code, Code.UNAVAILABLE); expect(e.message, 'Closed in non-idle state'); } }); @@ -84,7 +84,7 @@ void main() { await result; fail('Did not throw'); } on GrpcError catch (e) { - expect(e.code, StatusCode.unavailable); + expect(e.code, Code.UNAVAILABLE); expect(e.message, 'Closed in non-idle state'); } }); @@ -101,7 +101,7 @@ void main() { await result; fail('Did not throw'); } on GrpcError catch (e) { - expect(e.code, StatusCode.unimplemented); + expect(e.code, Code.UNIMPLEMENTED); expect(e.message, 'Received header while reading data'); } }); @@ -117,7 +117,7 @@ void main() { await result; fail('Did not throw'); } on GrpcError catch (e) { - expect(e.code, StatusCode.unimplemented); + expect(e.code, Code.UNIMPLEMENTED); expect(e.message, 'Received header while reading data'); } }); diff --git a/test/timeout_test.dart b/test/timeout_test.dart index 578a9d9e..84abf70b 100644 --- a/test/timeout_test.dart +++ b/test/timeout_test.dart @@ -132,7 +132,7 @@ void main() { harness ..service.unaryHandler = methodHandler - ..expectErrorResponse(StatusCode.deadlineExceeded, 'Deadline exceeded') + ..expectErrorResponse(Code.DEADLINE_EXCEEDED, 'Deadline exceeded') ..sendRequestHeader('/Test/Unary', timeout: Duration(microseconds: 1)); await harness.fromServer.done; });