-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Capture messenger exceptions #326
Capture messenger exceptions #326
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you a lot for this PR! I surely will have to work a bit to make the CI work. Also, can you add a changelog entry?
I would love to also have an end2end test for this... But I'm not sure it's feasible; I would leave it to the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last small nitpick remains (plus fixing the CI), great job!
Co-Authored-By: Alessandro Lai <[email protected]>
…rref/sentry-symfony into feature/capture-messenger-exceptions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks you so much for your contribution! I've added some non-code commits, now it's ready to merge!
Thanks for this PR! :) |
I'm waiting for #322 to be merged before preparing the 3.5 release. |
|
||
if ($error instanceof HandlerFailedException && null !== $error->getPrevious()) { | ||
// Unwrap the messenger exception to get the original error | ||
$error = $error->getPrevious(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HandlerFailedException
handles a collection of exceptions so getting only the previous may lose some information along the way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the use case there? What's the situation where the handler will report multiple exceptions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/symfony/messenger/blob/master/Middleware/HandleMessageMiddleware.php#L56-L69
Looks like when a command has multiple handlers, they will all run. Any throwable is caught and the next handler is continued.
So here, we should iterate over $error->getNestedExceptions()
and capture them all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or just capture HandlerFailedException
? Not sure about the pros and cons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since HandlerFailedException
is not naturally comprehensible to Sentry, capturing it isn't ideal, it shouldn't work out of the box: the event will not show enough information on the specific handlers nor the specific errors.
Just to be sure that I understood this correctly: multiple handlers will run together only if they are all sync and not async, right? If that's the case, at least it should be a non-so-common use case, so we don't have to rush the patch.
Opening #338 to track this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be sure that I understood this correctly: multiple handlers will run together only if they are all sync and not async, right?
No, I don't think so by reading the code and from what I understand about Messenger. Sync or Async does not matter. The only thing that matter is if there are multiple handlers for a Message or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sync or Async does not matter. The only thing that matter is if there are multiple handlers for a Message or not.
Correct. Each handler for a command will be run either to completion or to an exception. Subsequent handlers will be executed and previous exceptions aggregated and added to the HandlerFailedException. So even if one handler succeeds, another handler may fail and raise the exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, maybe I did not explain myself completely. For sync and async I was referring to the transport: if it's sync, the message is handled in the same request/process, and so it requires special handling on Sentry's side. If it's async, it should go through a queue (Rabbit? SQS?) so it will be executed inside a different process, and it's isolated as far as Sentry is concerned.
Does this still hold?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah if a command has multiple handlers, sync or async won’t matter. The handle middleware will execute them all in the same process, catching and aggregating errors as they’re thrown, to be later raised in the handler failed exception.
@emarref is the |
Yeah I've just confirmed it's working as expected for me. |
Ok great. I discovered that the issue is in the fact that |
Oh crap, issue found:
@emarref what do you get if you call |
I've opened #353 to dig further, it seems something changed between 4.3 and 4.4. |
No I haven't.
I am definitely seeing the error thrown in my handler appearing multiple times in Sentry for a single run. But the listeners don't seem to be in the right order as you've shown. I will take a look when I get more time over the next few days. Thanks for opening the PR. |
Errors that occur when handling Messenger messages asynchronously (e.g. background queue) are not captured or flushed to Sentry. This pull request addresses two issues;
Firstly, exceptions thrown during the execution of the Worker class are caught and logged, and therefore never captured by Sentry.
Secondly, captured messages are never flushed to Sentry unless the worker is configured to run with a limit (i.e.
--time-limit=3600
or--limit=10
).When a handler fails when executed via the Worker, Messenger dispatches an event. This pull request listens for this
WorkerMessageFailedEvent
, and captures the exception, then flushes immediately.Addresses #259 and #811.