Send trailers included on GrpcError object (#538)

This commit is contained in:
Rui Craveiro 2022-08-23 11:40:03 +01:00 committed by GitHub
parent af965f15f7
commit b8f872a3dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 2 deletions

View File

@ -328,7 +328,8 @@ class ServerHandler_ extends ServiceCall {
}
@override
void sendTrailers({int? status = 0, String? message}) {
void sendTrailers(
{int? status = 0, String? message, Map<String, String>? errorTrailers}) {
_timeoutTimer?.cancel();
final outgoingTrailersMap = <String, String>{};
@ -354,6 +355,9 @@ class ServerHandler_ extends ServiceCall {
outgoingTrailersMap['grpc-message'] =
Uri.encodeFull(message).replaceAll('%20', ' ');
}
if (errorTrailers != null) {
outgoingTrailersMap.addAll(errorTrailers);
}
final outgoingTrailers = <Header>[];
outgoingTrailersMap.forEach((key, value) =>
@ -407,7 +411,11 @@ class ServerHandler_ extends ServiceCall {
}
void _sendError(GrpcError error) {
sendTrailers(status: error.code, message: error.message);
sendTrailers(
status: error.code,
message: error.message,
errorTrailers: error.trailers,
);
}
void cancel() {

View File

@ -50,6 +50,22 @@ class TestServiceWithOnMetadataException extends TestService {
}
}
class TestServiceWithGrpcError extends TestService {
@override
Stream<int> stream(ServiceCall call, Future request) async* {
throw GrpcError.custom(
StatusCode.internal,
'This error should contain trailers',
null,
null,
{
'key1': 'value1',
'key2': 'value2',
},
);
}
}
class FixedConnectionClientChannel extends ClientChannelBase {
final Http2ClientConnection clientConnection;
List<ConnectionState> states = <ConnectionState>[];
@ -155,4 +171,30 @@ Future<void> main() async {
await channel.shutdown();
await server.shutdown();
});
test('trailers on server GrpcError', () async {
final server = Server([TestServiceWithGrpcError()]);
await server.serve(address: 'localhost', port: 0);
final channel = FixedConnectionClientChannel(Http2ClientConnection(
'localhost',
server.port!,
ChannelOptions(credentials: ChannelCredentials.insecure()),
));
final testClient = TestClient(channel);
await expectLater(
testClient.stream(TestService.requestFiniteStream).toList(),
throwsA(predicate<GrpcError>((e) {
final trailers = e.trailers;
if (trailers == null || trailers.length != 2) return false;
final entries = trailers.entries.toList();
final isOk = entries[0].key == 'key1' &&
entries[0].value == 'value1' &&
entries[1].key == 'key2' &&
entries[1].value == 'value2';
return isOk;
})),
);
await server.shutdown();
});
}