feat: Allow capturing exception on task execution - #3095
pbonneaudiabolocom wants to merge 3 commits into
Conversation
…ne to overload the task exception that could be generated.
|
Pursuing efforts of PR #2947 |
IvanKirpichnikov
left a comment
There was a problem hiding this comment.
Hi. Let’s do it this way: let the subscriber accept exception_handler: Callable[[BaseException], bool].
If exception_handler returns True, the exception is suppressed. If it returns False, the exception is considered unhandled, following the same logic as context managers.
This means that this hook should be available on every subscriber. Not only for redis
|
I don’t like this approach for several reasons: Before defining your own handler, you have to save the “old” one:
|
|
I agree, the issue is that you can't overload subscriber because it's provided by the broker. So, passing another argument, exception_handler: Callable[[BaseException], bool], is going to be as difficult as switching a method to replace it by another. After, my knowledge on how faststream works is limited. I'm a user, not so knowledgable about what's under the hood. The only object we do have access to is the broker, do we really want the broker to be the entry point for a subscriber exception manager ? I'm honnestly trying to find a way, but I find many average solution, but no good one when I'm satisfied by the result. |
I mean passing the exception_handler to the subscriber. Although, if we take the idea further, I think we could also support setting the exception_handler at the broker level, but the question arises as to what order to call them in. |
|
I still don't get how we are supposed to access the subscriber to do that. broker.subscriber.add_exception_handler() I mean, it could be done for sure, but then you'll come back quickly to something such as getting the default exception_handler for the subscriber, and replacing it by a function taht do some stuff and call the default one in case needed. I cannot figure what you want to do... |
I mean something like that. def global_exception_handler(exc: BaseException) -> bool:
if isinstance(exc, GlobalError):
...
return True
return False
broker = NatsBroker(..., exception_handler=global_exception_handler)
def my_exception_handler(exc: BaseException) -> bool:
if isinstance(exc, MyError):
# do custom logic
...
# i'm process error
return True
# i'm not process error
return False
@broker.subscriber("subject", exception_handler=my_exception_handler)
async def handle(body: Body):
if body.act == 1:
raise MyError
else:
raise GlobalError |
|
ok, so on top of the subscriber exception_handler, you want also a broker exception handler. That could be elegant. Are we allowing to overide the default exception handling, or to call it ? Because I think that's going to be a common usecase. Target an error, do a specific action, but let faststream defaut behaviour in any other usecases. |
My idea is as follows. First, the exception_handler is called for the subscriber. If it returns False, then the exception_handler for the broker is executed. If it also returns False, the default error handling is triggered. Is everything clear to you? If not, I’m ready to answer your questions. |
|
Hi, Your idea seems nice, but I'm not sure I'm the right one to implement it. I barely understand faststream logic, so except burning token, my value will be very low here... I don't know how I could assert anything... especially with such a large scope impact. |
|
It doesn’t seem too difficult. It’s worth a try. Patience and hard work will conquer all :) |
Description
It allows to customize the task exception managment + the consume error behaviour
Fixes #2945
Type of change
Please delete options that are not relevant.
Checklist
just lintshows no errors)just test-coveragejust static-analysis