diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 1dd0f0cbe..b11495c6f 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.12.4", + "version": "1.12.5", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index 6fc1e1eb5..d2b5f076a 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -190,7 +190,22 @@ export class Http2SubchannelCall implements SubchannelCall { try { messages = this.decoder.write(data); } catch (e) { - this.cancelWithStatus(Status.RESOURCE_EXHAUSTED, (e as Error).message); + /* Some servers send HTML error pages along with HTTP status codes. + * When the client attempts to parse this as a length-delimited + * message, the parsed message size is greater than the default limit, + * resulting in a message decoding error. In that situation, the HTTP + * error code information is more useful to the user than the + * RESOURCE_EXHAUSTED error is, so we report that instead. Normally, + * we delay processing the HTTP status until after the stream ends, to + * prioritize reporting the gRPC status from trailers if it is present, + * but when there is a message parsing error we end the stream early + * before processing trailers. */ + if (this.httpStatusCode !== undefined && this.httpStatusCode !== 200) { + const mappedStatus = mapHttpStatusCode(this.httpStatusCode); + this.cancelWithStatus(mappedStatus.code, mappedStatus.details); + } else { + this.cancelWithStatus(Status.RESOURCE_EXHAUSTED, (e as Error).message); + } return; }