Preserve OperationCanceledException for explicitly requested cancellation instead of being wrapping it in ApiRequestException #2162
Replies: 2 comments
-
|
I can see your position on the way we do ApiExceptions, so potentially it's likely a regression in some regards. Probably worth raising an issue. |
Beta Was this translation helpful? Give feedback.
-
|
Agreed - wrapping a caller-requested cancellation (OperationCanceledException from your own CancellationToken) in ApiRequestException is a regression from the pre-v11 behavior. Intentional cancellation is control flow, not a transport error, and should propagate unwrapped so ASP.NET Core abort handling, Polly, and plain catch (OperationCanceledException) work as expected. I've opened a tracking issue with repro, the timeout-vs-cancellation distinction, and implementation/test notes: #2188 Genuine HttpClient.Timeout cancellations (token not signalled) will keep the current ApiRequestException wrapping so real timeouts are still reported as request errors. Let's continue on the issue. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
First of all, thanks for the amazing work on Refit 11! I understand the motivation behind #2052. Having ApiRequestException and a unified ApiExceptionBase model is a valuable improvement.
I would like to discuss one specific edge case though: caller-requested cancellation.
Since v11.0, all exceptions thrown by HttpClient.SendAsync are wrapped into ApiRequestException:
refit/src/Refit/RequestExecutionHelpers.cs
Lines 322 to 351 in 196cd49
However, I think there is an important semantic difference between:
OperationCanceledException caused by the caller’s token cancellation is generally not treated as an application/infrastructure error. It is control flow. Many applications intentionally let it bubble up so that ASP.NET Core, background workers, logging middleware, retry policies, and tracing systems can classify it correctly as cancellation rather than failure.
I would normally expect this pattern to keep working:
With the current v11 behavior, it requires something closer to:
or a bit more tricky with the ApiResponse way
I am not arguing against ApiRequestException in general. The new model is useful for real transport failures and for carrying request context. My concern is specifically about intentional cancellation, which usually has a different semantic from a failed http request and is expected to bubble up as is.
What's your point of view on that?
Thank you!
Beta Was this translation helpful? Give feedback.
All reactions