"Non-Error exception captured with keys: [...]" due to invalid error instanceof check
See original GitHub issueIs there an existing issue for this?
- I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- I have reviewed the documentation https://docs.sentry.io/
- I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Self-hosted/on-premise
Which package are you using?
SDK Version
7.7.0
Framework Version
Angular 13.3 & Ionic 5
Link to Sentry event
No response
Steps to Reproduce
// Case1: capture string
Sentry.captureException('foo);
// Case2: capture error-like object
Sentry.captureException({
name: 'FooError',
message: 'foo',
});
// Case3: throw string
throw 'foo';
// Case4: throw error-like object
throw {
name: 'FooError',
message: 'foo',
};
// Case5: capture string with the SentryAngular ErrorHandler
this.errorHandler.handleError('foo');
// Case6: capture error-like object with the SentryAngular ErrorHandler
this.errorHandler.handleError({
name: 'FooError',
message: 'foo',
});
Expected Result
The first problem I identify here is the incorrect handling of error like objects. I suspect this is due to this line:
if (typeof error === 'string' || error instanceof Error) {
return error;
}
I am really not convinced an instanceof
should be used here. Having a type guard to check for an error like object (it could also have a quick instanceof under the hood), would make more sense and also be more in line with the philosophy of TypeScript where types are checked as structures, instead of instances.
The second problem I see is the difference of handling when an error is thrown, captured by Sentry manually or passed to the error handler.
That there is a difference between Sentry.captureException()
and ErrorHandler.handle()
makes sense since the latter is using the former under the hood. But I think having a difference of handling for when an error is thrown instead of passed to the error handler is a lot more surprising.
I however could not find where the global listener is registered and check the problematic code or figure out a way to fix this.
Actual Result
// Case1: capture string Nothing captured!
// Case2: capture error-like object
captureException
Non-Error exception captured with keys: message, name
// Case3: throw string Nothing captured!
// Case4: throw error-like object
Error resolvePromise(polyfills)
Uncaught (in promise): Object: {"name":"FooError","message":"foo"}
// Case5: capture string with the SentryAngular ErrorHandler Nothing captured!
// Case6: capture error-like object with the SentryAngular ErrorHandler Nothing captured!
Issue Analytics
- State:
- Created 10 months ago
- Comments:5 (5 by maintainers)
Thanks a lot for the reply.
I’ll give another try at the handling of strings. If it works on your side, since the code is up to date, the last possible culprit is that our Sentry instance is faulty or there is a weird ignore rule or something. I didn’t really think of that when I posted the issue, I will check.
Otherwise it looks at the very least that we all agree on the undesired instance of Error. So I can do a PR for that.
I think what @AbhiPrasad meant was that having a stack trace is better than not having one, as it just provides a lot more context around the captured error. The Angular
ErrorHandler
should handle strings fine. But according to your description, cases 1, 3 and 5 regardless of the method, string “errors” aren’t captured at all. This is weird because when I try to capture strings (Sentry.captureException('Test String Error');
), the error shows up in Sentry.You mean you’d like to capture errors captured in
window.onerror
via the AngularErrorHandler
? Not sure if this works but you could try disabling theGlobalHandlers
integration and adding your own handler towindow.onerror
which does that?Btw, if you want to change how errors are extracted from the Angular ErrorHandler, you can pass a custom extractor to the ErrorHandler’s constructor