question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

"Non-Error exception captured with keys: [...]" due to invalid error instanceof check

See original GitHub issue

Is there an existing issue for this?

How do you use Sentry?

Self-hosted/on-premise

Which package are you using?

@sentry/angular

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:open
  • Created 10 months ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
theofidrycommented, Dec 3, 2022

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.

0reactions
Lms24commented, Dec 5, 2022

Is it really necessary?

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.

is there any chance/recommendation as too how to hook the Angular error handler instead of this? Or do they need to be different?

You mean you’d like to capture errors captured in window.onerror via the Angular ErrorHandler? Not sure if this works but you could try disabling the GlobalHandlers integration and adding your own handler to window.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

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why am I seeing events with "Non-Error exception (or promise ...
If you're seeing errors having the message "Non-Error exception (or promise rejection) captured with keys: x, y, z.
Read more >
checking for typeof error in JS - javascript - Stack Overflow
In that case, the instanceof Error check will return false, even for an Error object. In that case, the easiest approach is duck-typing....
Read more >
Improving TypeScript error handling with exhaustive type ...
Discover an improved method for handling errors in TypeScript that solves problems that arise from returning null and throwing try...catch.
Read more >
Exceptions - Manual - PHP
The thrown object must be an instanceof Throwable. ... If an exception is not caught, a PHP Fatal Error will be issued with...
Read more >
API Reference | Vitest
test defines a set of related expectations. ... test.skip('skipped test', () => { // Test skipped, no error assert.equal(Math.sqrt(4), 3) }) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found