sentry-javascript: Very uninformative onunhandledrejection errors when rejecting with Event
- Review the documentation: https://docs.sentry.io/
- Search for existing issues: https://github.com/getsentry/sentry-javascript/issues
- Use the latest release: https://github.com/getsentry/sentry-javascript/releases
- Provide a link to the affected event from your Sentry account
Package + Version
-
@sentry/browser -
@sentry/node -
raven-js -
raven-node(raven for node) - other:
Version:
5.6.2
Description
Errors captured through onunhandledrejection mechanism never really provide any useful information that would help in figuring out the problem.
In my app, I have thousands (17K as of now for one of them, after few months) of UnhandledRejection errors. All info that those events provide is just a an error text like UnhandledRejection: "CustomEvent" (note that with latest version of Sentry it became a little bit more informative with UnhandledRejection: Non-Error promise rejection captured with keys: isTrusted text). There is no stack nor extra context and those errors happen on routes and paths that work perfectly for me and everyone I know so I’m unable figure out how to address them.
Now, I assume, that the problem is only with unhandled promise rejections that reject with non-Error type like primitive values (string, null, etc.) or (like in this case) an Event object. While I don’t see how to improve cases with primitive values, I think for event objects, more data could be logged.
It seems the UnhandledRejection: Non-Error promise rejection captured with keys: isTrusted message comes from the fact that isTrusted is the only iterable key on the event object (try console.log(Object.keys(new CustomEvent('test')))). But event objects have more useful (non-iterable) keys that could provide more information about the error. Namely I’m thinking about detail and type properties. I think those could help identifying from which code event is coming from.
So I’m suggesting to add some custom code (if there isn’t already) for handling that special case (unhandledrejection with event object) better.
Some example events: https://sentry.io/share/issue/4d294f75e9704103b7c3b49e62b6e278/ https://sentry.io/share/issue/c36904ab4c224fbda6f1afff63c106ee/ (these are minimal, sharable versions but full events don’t really provide any other meaningful information either.)
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 72
- Comments: 74 (15 by maintainers)
I’m currently receiving thousands of instances of this error from a relatively small number of users. Since I’m just testing out Sentry right now with a free plan, there’s no way to filter them out. Spike Protection also does not seem to react to this issue.
I scheduled better
Event/CustomEventhandling work for the next week. Will keep everyone posted on this one.@mogelbrod is there a way you can provide a repro-case for this? We never had an issue with TraceKit incorrectly detecting Error instances.
As for your additional enumerables, we have an integration for this – https://docs.sentry.io/platforms/javascript/#extraerrordata
is basically equivalent of your
beforeSendsnippet.It would be amazing if Sentry had a built-in mechanism to also intelligently auto-filter unhandled rejection errors from extensions!
I wonder if these “installed outside of web store” extensions can also be filtered out with the
Filter out errors known to be caused by browser extensionscheckbox.Hey, I found where are they coming from in our project. They actuall come from
onerrorhandler for element like<img>. Ifis used, the rejected
ewill be anEventtype according to https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerrorThe same apply to XMLHttpRequest.onerror which gives
ProgressEvent. There is also XMLHttpRequest.timeout which givesundefinedAlso experiencing
isTrustedissues.Updating to the beta version helped, and extra info seems to be serialized & sent correctly.
In our case, the error turned out to originate from a Chrome extension. What’s interesting, we have the Filter out errors known to be caused by browser extensions option turned on, so it seems like the filtering mechanism does not always work.
Raw additional data:
I believe the
haldlgldplgnggkjaafhelgiaglafanhID is that of an unlisted extension called “GoGuardian Beacon”. See the screenshot in step 12 of Beacon’s installation manual. GoGuardian is a company that makes software tracking students. They may have cloned the HTML Content Blocker extension, rebranding & unlisting their copy for commercial use, which is why HTML Content Blocker’s fingerprint is present instead of Beacon’s.A student on a device with GoGuardian Beacon (force-)installed and using Sentry probably caused the error.
@kiruh it should be easily filtered with per-project setting:
Hello @OliverJAsh, we have the same uninformative logs as your case at the serialized section
{ currentTarget: [object Window], detail: None, isTrusted: [Circular ~], target: [object Window], type: unhandledrejection }. Have you found a solution?Since 5.7.0 we see a spike in such messages, especially
Non-Error exception captured with keys: currentTarget, isTrusted, target, type. Maybe there was a change in the latest release that causes that?I just rolled out
5.7.0-beta. Would appreciate testing it out viaIt improves events serialization and unifies some differences between reject/onerror/manual error handling. It also removes any dependencies that were necessary for IE10/11, including Promises, so we have to make sure it’s working correctly.
Any feedback appreciated! 😃
@Jun711:
A quick Google search for
haldlgldplgnggkjaafhelgiaglafanhyielded a few results indicating this “extension” might indeed be a malicious script.Notice this:
It looks like it’s trying to log in as a user with “owner” rights, and the query params always look the same. More than one search result mentions an online learning platform called Go Guardian (see the Google search page above).
Interestingly enough, there is no extension with such an id in the Chrome Store. If you look up any existing Chrome extension by its id, it will pop up in search results.
Wrapping a non-Error in Error was just to get the correct format for compatibility and also typing.
I have experienced several third party libraries that throw objects that have some information about the error but the nature of the error is . It is somewhere between an event and an error.
For instance, Google Analytics throws this object:
Which is an error that I’d like to know about in Sentry and it makes it all of the way to Sentry’s captureException, but google throws it as an object instead of an Error (as far as I can tell), so Sentry doesn’t handle it in the a way that is intuitive to me.
Javascript users should throw Errors, but the language allows them to throw plain objects, and sometimes they do. Those objects often contain error information that is helpful for debugging (the google example tells me everything I need to know) even without a stacktrace
A dynamic version of @rchl 's strategy would make sense to me – iterate through the object keys and attach them to
event.extra@kamilogorek I tried the solution you suggest (implement a beforeSend inside the init) but the error seems to be still sent, yet with fewer information (detail object becomes ‘None’ ). Do you have any other advice to filter out this specific error ? Thank you.
Same issue today with this extension & version 5.15.0 upgraded to 5.15.5: https://sentry.io/share/issue/3461d17193c64e1d980cd6d41a66ba23/
@Jun711
That was my instinct as well. If all the results seem to be connected to one digital product, chances are, this Chrome extension is an add-on to that platform. What’s unclear is why it attempts to do its thing on other origins. Could be malice, could be Hanlon’s razor.
No. If that’s an attack, then it’s a poor one.
We saw that as well. It’s because more keys are extracted while the
isTrustedis the only one that can be deserialized.Version: 5.15.5
I have tried to reduce an error noise by setting ignoreErrors and blacklistUrls as described here https://docs.sentry.io/platforms/javascript/#decluttering-sentry
Yet I still receive those errors.
Is there anything I can do? Because it’s eating my quota.
I’ve got 75K events from this chrome extension and it ate my quota
@kamilogorek should a new issue be opened?
@Jun711 https://chrome.google.com/webstore/detail/html-content-blocker/nobnkgabkebhhlgfddbemmefjnjnahoe?hl=en
As this thread got really large. First, please update the version of the SDK to the newest one, and then please open a new issue detailing what, where and how it is happening, so we can start to fix them one by one. Thanks!
@antoinerousseau thanks for clarifying, don’t know how I missed that 😅 I was thinking specifically of these unhandled rejection errors, though. I’ll edit my comment so it’s clear!
@vitorbal there already is such mechanism, please read the thread again, it’s just not always working perfectly https://github.com/getsentry/sentry-javascript/issues/2210#issuecomment-540022105
@kamilogorek IIUC, exceptions and promise rejections both have stacktraces (
error.stack, assuming the value is anError). I understand there are separate mechanisms for handling exceptions and promise rejections, but I don’t see why that means we can’t give them equal treatment?As a user, ideally all extension errors would be filtered out.
@ajhool yep, I’ll probably do that if the issue persists and I decide to keep using Sentry. I thought it might be helpful to report the impact to this Issue discussion.
I’m experiencing this, too, and I think that Sentry needs to handle non-Error types properly, rather than treating them like an error.
I’m still working through the problem and I tried adding this code to wrap objects in an Error type, but this didn’t fix the problem:
Next, I’m going to try using
Sentry.captureMessageif the instance type is not an Error, but a lot of third party libraries throw non-Error types that should be treated as Errors in Sentry IMOI would actually disagree with the title of this issue – I don’t think that Sentry is being uninformative, I think it’s actually informing developers that Sentry doesn’t properly handle some types of common javascript errors (ie. thrown objects that aren’t of instance type: Error). I see this as being an actual bug in Sentry, because a thrown Object in javascript is still an Exception/Error, even if the thrown object is not of Error type IMO. I’m not sure where the javascript community would stand on this, admittedly (https://stackoverflow.com/questions/9156176/what-is-the-difference-between-throw-new-error-and-throw-someobject)