From e69a00dee63eb589ccfcf637a9a911368600ea4d Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Wed, 22 Nov 2023 16:20:21 +0530 Subject: [PATCH 1/4] Capture header in `ConnecError` for gRPC unary call --- packages/connect-web/src/grpc-web-transport.ts | 4 ++-- packages/connect/src/protocol-grpc-web/transport.ts | 4 ++-- packages/connect/src/protocol-grpc/transport.ts | 4 ++-- packages/connect/src/protocol-grpc/validate-trailer.ts | 8 +++++++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/connect-web/src/grpc-web-transport.ts b/packages/connect-web/src/grpc-web-transport.ts index fbce76f13..2941135a9 100644 --- a/packages/connect-web/src/grpc-web-transport.ts +++ b/packages/connect-web/src/grpc-web-transport.ts @@ -213,7 +213,7 @@ export function createGrpcWebTransport( if (trailer === undefined) { throw "missing trailer"; } - validateTrailer(trailer); + validateTrailer(trailer, response.headers); if (message === undefined) { throw "missing message"; } @@ -279,7 +279,7 @@ export function createGrpcWebTransport( } trailerReceived = true; const trailer = trailerParse(data); - validateTrailer(trailer); + validateTrailer(trailer, undefined); trailer.forEach((value, key) => trailerTarget.set(key, value)); continue; } diff --git a/packages/connect/src/protocol-grpc-web/transport.ts b/packages/connect/src/protocol-grpc-web/transport.ts index 50815ed68..43b6e9193 100644 --- a/packages/connect/src/protocol-grpc-web/transport.ts +++ b/packages/connect/src/protocol-grpc-web/transport.ts @@ -169,7 +169,7 @@ export function createTransport(opt: CommonTransportOptions): Transport { Code.InvalidArgument, ); } - validateTrailer(trailer); + validateTrailer(trailer, uRes.header); if (message === undefined) { throw new ConnectError( "protocol error: missing output message for unary method", @@ -305,7 +305,7 @@ export function createTransport(opt: CommonTransportOptions): Transport { ); } trailerReceived = true; - validateTrailer(chunk.value); + validateTrailer(chunk.value, undefined); chunk.value.forEach((value, key) => res.trailer.set(key, value), ); diff --git a/packages/connect/src/protocol-grpc/transport.ts b/packages/connect/src/protocol-grpc/transport.ts index 3dc87b0e9..fa75c96af 100644 --- a/packages/connect/src/protocol-grpc/transport.ts +++ b/packages/connect/src/protocol-grpc/transport.ts @@ -144,7 +144,7 @@ export function createTransport(opt: CommonTransportOptions): Transport { }, { propagateDownStreamError: false }, ); - validateTrailer(uRes.trailer); + validateTrailer(uRes.trailer, uRes.header); if (message === undefined) { throw new ConnectError( "protocol error: missing output message for unary method", @@ -245,7 +245,7 @@ export function createTransport(opt: CommonTransportOptions): Transport { async function* (iterable) { yield* iterable; if (!foundStatus) { - validateTrailer(uRes.trailer); + validateTrailer(uRes.trailer, undefined); } }, { propagateDownStreamError: true }, diff --git a/packages/connect/src/protocol-grpc/validate-trailer.ts b/packages/connect/src/protocol-grpc/validate-trailer.ts index 01263245f..047263944 100644 --- a/packages/connect/src/protocol-grpc/validate-trailer.ts +++ b/packages/connect/src/protocol-grpc/validate-trailer.ts @@ -20,9 +20,15 @@ import { findTrailerError } from "./trailer-status.js"; * * @private Internal code, does not follow semantic versioning. */ -export function validateTrailer(trailer: Headers): void { +export function validateTrailer( + trailer: Headers, + header: Headers | undefined, +): void { const err = findTrailerError(trailer); if (err) { + header?.forEach((value, key) => { + err.metadata.append(key, value); + }); throw err; } } From e540f87787c7bba42b33bc532d54572ee8a6bd05 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Fri, 24 Nov 2023 11:33:06 +0530 Subject: [PATCH 2/4] Pass headers in streams --- packages/connect-web/src/grpc-web-transport.ts | 5 +++-- packages/connect/src/protocol-grpc-web/transport.ts | 2 +- packages/connect/src/protocol-grpc/transport.ts | 2 +- packages/connect/src/protocol-grpc/validate-trailer.ts | 7 ++----- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/connect-web/src/grpc-web-transport.ts b/packages/connect-web/src/grpc-web-transport.ts index 2941135a9..58bee0ddd 100644 --- a/packages/connect-web/src/grpc-web-transport.ts +++ b/packages/connect-web/src/grpc-web-transport.ts @@ -250,6 +250,7 @@ export function createGrpcWebTransport( body: ReadableStream, foundStatus: boolean, trailerTarget: Headers, + header: Headers, ) { const reader = createEnvelopeReadableStream(body).getReader(); if (foundStatus) { @@ -279,7 +280,7 @@ export function createGrpcWebTransport( } trailerReceived = true; const trailer = trailerParse(data); - validateTrailer(trailer, undefined); + validateTrailer(trailer, header); trailer.forEach((value, key) => trailerTarget.set(key, value)); continue; } @@ -348,7 +349,7 @@ export function createGrpcWebTransport( ...req, header: fRes.headers, trailer, - message: parseResponseBody(fRes.body, foundStatus, trailer), + message: parseResponseBody(fRes.body, foundStatus, trailer, fRes.headers), }; return res; }, diff --git a/packages/connect/src/protocol-grpc-web/transport.ts b/packages/connect/src/protocol-grpc-web/transport.ts index 43b6e9193..6efcacf6d 100644 --- a/packages/connect/src/protocol-grpc-web/transport.ts +++ b/packages/connect/src/protocol-grpc-web/transport.ts @@ -305,7 +305,7 @@ export function createTransport(opt: CommonTransportOptions): Transport { ); } trailerReceived = true; - validateTrailer(chunk.value, undefined); + validateTrailer(chunk.value, uRes.header); chunk.value.forEach((value, key) => res.trailer.set(key, value), ); diff --git a/packages/connect/src/protocol-grpc/transport.ts b/packages/connect/src/protocol-grpc/transport.ts index fa75c96af..fbde90456 100644 --- a/packages/connect/src/protocol-grpc/transport.ts +++ b/packages/connect/src/protocol-grpc/transport.ts @@ -245,7 +245,7 @@ export function createTransport(opt: CommonTransportOptions): Transport { async function* (iterable) { yield* iterable; if (!foundStatus) { - validateTrailer(uRes.trailer, undefined); + validateTrailer(uRes.trailer, uRes.header); } }, { propagateDownStreamError: true }, diff --git a/packages/connect/src/protocol-grpc/validate-trailer.ts b/packages/connect/src/protocol-grpc/validate-trailer.ts index 047263944..145bdfe1c 100644 --- a/packages/connect/src/protocol-grpc/validate-trailer.ts +++ b/packages/connect/src/protocol-grpc/validate-trailer.ts @@ -20,13 +20,10 @@ import { findTrailerError } from "./trailer-status.js"; * * @private Internal code, does not follow semantic versioning. */ -export function validateTrailer( - trailer: Headers, - header: Headers | undefined, -): void { +export function validateTrailer(trailer: Headers, header: Headers): void { const err = findTrailerError(trailer); if (err) { - header?.forEach((value, key) => { + header.forEach((value, key) => { err.metadata.append(key, value); }); throw err; From f67bce1bef6b873883272b2989c8ab7f3bf1e9c5 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Fri, 24 Nov 2023 12:03:33 +0530 Subject: [PATCH 3/4] Handle for connect protocol --- packages/connect-web/src/connect-transport.ts | 9 +++++++-- packages/connect-web/src/grpc-web-transport.ts | 7 ++++++- packages/connect/src/protocol-connect/transport.ts | 6 +++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/connect-web/src/connect-transport.ts b/packages/connect-web/src/connect-transport.ts index fea7b6cf7..48fdbfa91 100644 --- a/packages/connect-web/src/connect-transport.ts +++ b/packages/connect-web/src/connect-transport.ts @@ -258,6 +258,7 @@ export function createConnectTransport( async function* parseResponseBody( body: ReadableStream, trailerTarget: Headers, + header: Headers, ) { const reader = createEnvelopeReadableStream(body).getReader(); let endStreamReceived = false; @@ -271,7 +272,11 @@ export function createConnectTransport( endStreamReceived = true; const endStream = endStreamFromJson(data); if (endStream.error) { - throw endStream.error; + const error = endStream.error; + header.forEach((value, key) => { + error.metadata.append(key, value); + }); + throw error; } endStream.metadata.forEach((value, key) => trailerTarget.set(key, value), @@ -346,7 +351,7 @@ export function createConnectTransport( ...req, header: fRes.headers, trailer, - message: parseResponseBody(fRes.body, trailer), + message: parseResponseBody(fRes.body, trailer, fRes.headers), }; return res; }, diff --git a/packages/connect-web/src/grpc-web-transport.ts b/packages/connect-web/src/grpc-web-transport.ts index 58bee0ddd..d61047b61 100644 --- a/packages/connect-web/src/grpc-web-transport.ts +++ b/packages/connect-web/src/grpc-web-transport.ts @@ -349,7 +349,12 @@ export function createGrpcWebTransport( ...req, header: fRes.headers, trailer, - message: parseResponseBody(fRes.body, foundStatus, trailer, fRes.headers), + message: parseResponseBody( + fRes.body, + foundStatus, + trailer, + fRes.headers, + ), }; return res; }, diff --git a/packages/connect/src/protocol-connect/transport.ts b/packages/connect/src/protocol-connect/transport.ts index 3cf9d141c..a1339052c 100644 --- a/packages/connect/src/protocol-connect/transport.ts +++ b/packages/connect/src/protocol-connect/transport.ts @@ -289,7 +289,11 @@ export function createTransport(opt: CommonTransportOptions): Transport { } endStreamReceived = true; if (chunk.value.error) { - throw chunk.value.error; + const error = chunk.value.error; + uRes.header.forEach((value, key) => { + error.metadata.append(key, value); + }); + throw error; } chunk.value.metadata.forEach((value, key) => res.trailer.set(key, value), From aab37f7baa49d9cf6afaed2b5179281023879ea6 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Fri, 24 Nov 2023 12:20:08 +0530 Subject: [PATCH 4/4] bench --- packages/connect-web-bench/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/connect-web-bench/README.md b/packages/connect-web-bench/README.md index 619786049..1f7863171 100644 --- a/packages/connect-web-bench/README.md +++ b/packages/connect-web-bench/README.md @@ -10,5 +10,5 @@ it like a web server would usually do. | code generator | bundle size | minified | compressed | |----------------|-------------------:|-----------------------:|---------------------:| -| connect | 115,395 b | 50,680 b | 13,669 b | +| connect | 115,578 b | 50,754 b | 13,683 b | | grpc-web | 414,071 b | 300,352 b | 53,255 b |