Skip to content

Commit 7c833af

Browse files
committed
Pass exception to metadata interceptors
1 parent 9a3fc2b commit 7c833af

3 files changed

Lines changed: 205 additions & 14 deletions

File tree

src/connectrpc/_interceptor_async.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ async def on_start(self, ctx: RequestContext) -> T:
136136
"""
137137
...
138138

139-
async def on_end(self, token: T, ctx: RequestContext) -> None:
139+
async def on_end(
140+
self, token: T, ctx: RequestContext, error: Exception | None
141+
) -> None:
140142
"""Called when the RPC ends."""
141143
return
142144

@@ -164,10 +166,14 @@ async def intercept_unary(
164166
ctx: RequestContext,
165167
) -> RES:
166168
token = await self._delegate.on_start(ctx)
169+
error: Exception | None = None
167170
try:
168171
return await call_next(request, ctx)
172+
except Exception as e:
173+
error = e
174+
raise
169175
finally:
170-
await self._delegate.on_end(token, ctx)
176+
await self._delegate.on_end(token, ctx, error)
171177

172178
async def intercept_client_stream(
173179
self,
@@ -176,10 +182,14 @@ async def intercept_client_stream(
176182
ctx: RequestContext,
177183
) -> RES:
178184
token = await self._delegate.on_start(ctx)
185+
error: Exception | None = None
179186
try:
180187
return await call_next(request, ctx)
188+
except Exception as e:
189+
error = e
190+
raise
181191
finally:
182-
await self._delegate.on_end(token, ctx)
192+
await self._delegate.on_end(token, ctx, error)
183193

184194
async def intercept_server_stream(
185195
self,
@@ -188,11 +198,15 @@ async def intercept_server_stream(
188198
ctx: RequestContext,
189199
) -> AsyncIterator[RES]:
190200
token = await self._delegate.on_start(ctx)
201+
error: Exception | None = None
191202
try:
192203
async for response in call_next(request, ctx):
193204
yield response
205+
except Exception as e:
206+
error = e
207+
raise
194208
finally:
195-
await self._delegate.on_end(token, ctx)
209+
await self._delegate.on_end(token, ctx, error)
196210

197211
async def intercept_bidi_stream(
198212
self,
@@ -201,11 +215,15 @@ async def intercept_bidi_stream(
201215
ctx: RequestContext,
202216
) -> AsyncIterator[RES]:
203217
token = await self._delegate.on_start(ctx)
218+
error: Exception | None = None
204219
try:
205220
async for response in call_next(request, ctx):
206221
yield response
222+
except Exception as e:
223+
error = e
224+
raise
207225
finally:
208-
await self._delegate.on_end(token, ctx)
226+
await self._delegate.on_end(token, ctx, error)
209227

210228

211229
def resolve_interceptors(

src/connectrpc/_interceptor_sync.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ def on_start_sync(self, ctx: RequestContext) -> T:
136136
"""
137137
...
138138

139-
def on_end_sync(self, token: T, ctx: RequestContext) -> None:
139+
def on_end_sync(
140+
self, token: T, ctx: RequestContext, error: Exception | None
141+
) -> None:
140142
"""Called when the RPC ends."""
141143
return
142144

@@ -164,10 +166,14 @@ def intercept_unary_sync(
164166
ctx: RequestContext,
165167
) -> RES:
166168
token = self._delegate.on_start_sync(ctx)
169+
error: Exception | None = None
167170
try:
168171
return call_next(request, ctx)
172+
except Exception as e:
173+
error = e
174+
raise
169175
finally:
170-
self._delegate.on_end_sync(token, ctx)
176+
self._delegate.on_end_sync(token, ctx, error)
171177

172178
def intercept_client_stream_sync(
173179
self,
@@ -176,10 +182,14 @@ def intercept_client_stream_sync(
176182
ctx: RequestContext,
177183
) -> RES:
178184
token = self._delegate.on_start_sync(ctx)
185+
error: Exception | None = None
179186
try:
180187
return call_next(request, ctx)
188+
except Exception as e:
189+
error = e
190+
raise
181191
finally:
182-
self._delegate.on_end_sync(token, ctx)
192+
self._delegate.on_end_sync(token, ctx, error)
183193

184194
def intercept_server_stream_sync(
185195
self,
@@ -188,10 +198,14 @@ def intercept_server_stream_sync(
188198
ctx: RequestContext,
189199
) -> Iterator[RES]:
190200
token = self._delegate.on_start_sync(ctx)
201+
error: Exception | None = None
191202
try:
192203
yield from call_next(request, ctx)
204+
except Exception as e:
205+
error = e
206+
raise
193207
finally:
194-
self._delegate.on_end_sync(token, ctx)
208+
self._delegate.on_end_sync(token, ctx, error)
195209

196210
def intercept_bidi_stream_sync(
197211
self,
@@ -200,10 +214,14 @@ def intercept_bidi_stream_sync(
200214
ctx: RequestContext,
201215
) -> Iterator[RES]:
202216
token = self._delegate.on_start_sync(ctx)
217+
error: Exception | None = None
203218
try:
204219
yield from call_next(request, ctx)
220+
except Exception as e:
221+
error = e
222+
raise
205223
finally:
206-
self._delegate.on_end_sync(token, ctx)
224+
self._delegate.on_end_sync(token, ctx, error)
207225

208226

209227
def resolve_interceptors(

0 commit comments

Comments
 (0)