diff --git a/packages/grpc-js/src/metadata-status-filter.ts b/packages/grpc-js/src/metadata-status-filter.ts index 5ca401f7..52c27682 100644 --- a/packages/grpc-js/src/metadata-status-filter.ts +++ b/packages/grpc-js/src/metadata-status-filter.ts @@ -38,7 +38,7 @@ export class MetadataStatusFilter extends BaseFilter implements Filter { metadata.remove('grpc-status'); } if (typeof metadataMap['grpc-message'] === 'string') { - details = decodeURI(metadataMap['grpc-message'] as string); + details = decodeURIComponent(metadataMap['grpc-message'] as string); metadata.remove('grpc-message'); } return { code, details, metadata }; diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 02353bbe..b755b5e6 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -484,7 +484,9 @@ export class Http2ServerCallStream< const trailersToSend = Object.assign( { [GRPC_STATUS_HEADER]: statusObj.code, - [GRPC_MESSAGE_HEADER]: encodeURI(statusObj.details as string), + [GRPC_MESSAGE_HEADER]: encodeURIComponent( + statusObj.details as string + ), }, statusObj.metadata.toHttp2Headers() ); diff --git a/packages/grpc-js/test/test-server-errors.ts b/packages/grpc-js/test/test-server-errors.ts index ffabaac5..7c611b9b 100644 --- a/packages/grpc-js/test/test-server-errors.ts +++ b/packages/grpc-js/test/test-server-errors.ts @@ -699,6 +699,18 @@ describe('Other conditions', () => { } ); }); + + it('for an error message with a comma', done => { + client.unary( + { error: true, message: 'an error message, with a comma' }, + (err: ServiceError, data: any) => { + assert(err); + assert.strictEqual(err.code, grpc.status.UNKNOWN); + assert.strictEqual(err.details, 'an error message, with a comma'); + done(); + } + ); + }); }); });