Skip to content
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

If stacktrace has not the standard format error won't show up in dashboard #241

Closed
luisatmaniak opened this issue Jun 2, 2017 · 7 comments

Comments

@luisatmaniak
Copy link

While using window.fetch and Bugsnag.enableNotifyUnhandledRejections when an error occurs, somehow the stacktrace gets lost causing bugsnag.js to send stacktrace:TypeError: Failed to fetch to bugsnag's servers, which in turn makes the error non-visible on the dashboard.

I suspect this has to do with the expected format for stacktrace

@jmshal
Copy link

jmshal commented Jun 2, 2017

Hi, @luisatmaniak.

If I'm understanding this issue correctly, you're finding that the part of the stacktrace from before making the call to fetch() is being omitted from the error report?

While you may be seeing something like this in your dev tools (if you async stacktraces enabled)...

screenshot 2017-06-03 10 57 41

... the JS context only receives the uppermost portion of the stacktrace - the part above where it says Promise (async). And that's what gets sent to Bugsnag. It is also the case for JS timers like setTimeout.

If this isn't it, please would you be able to provide a snippet of code that can be used to replicate the issue?

@luisatmaniak
Copy link
Author

Yes, that's it. The async stacktrace is lost, and it just sends a string with little information. Here's my current workaround:

Bugsnag.beforeNotify = (error) => {
  error.stacktrace = error.stacktrace.replace(/chrome-extension/g, 'chrome_extension');

  if (!error.stacktrace.match(/at .+$/)) {
    error.stacktrace = error.stacktrace + '\n    at x (unknown:0:0)';
  }
};

As you can see this comes from a chrome extension, I replace chrome-extension as per the documentation.

@jmshal
Copy link

jmshal commented Jun 3, 2017

From my own personal tests, it doesn't seem possible to retrieve the full stacktrace in JavaScript, but I'll do some more experiments to see if there's anything that can be done to, at least, make the situation better.

Though I don't see there ever being a nice solution to this when using things like window.onerror or unhandledRejection unless browsers add support for in-JS async stacktraces.

I had a thought about maybe something like this;

function something() {
    fetch('https://example.com')
        .then(res => throw new Error('Simulate something bad happening'))
        .catch(Bugsnag.asyncNotifyException());
}

Where Bugsnag.asyncNotifyException generates a stacktrace when it is called, saves it, and then returns a function. When that function is later called as part of the Promise (catch), it manually combines the two stacktraces together & calls Bugsnag.notifyException.

This, of course, will not work with unhandledRejection, but it's better than nothing. And in reality, code in our control should handle errors sensibly.

Just an idea.

@bengourley
Copy link
Contributor

As @jmshal explained, async stack traces are not a "solved" problem in JS at the time of writing. We await a time when we can hook into them, but for now I'm closing this as it isn't a bug with the library, nor an issue we can deal with at this point in time.

@phillt
Copy link

phillt commented Jan 7, 2022

Wondering if this was ever solved, some 5 years later.

@xljones
Copy link
Contributor

xljones commented Jan 11, 2022

👋 hey @phillt, stacktraces will get sent to Bugsnag from the point where the async function (i.e. the async level where the error occurred) was called. However, JavaScript (at time of writing!) does not include frames before the async call to event listeners.

So with the following, calling fb1():

function fb1() {
  goFetch();
}
function goFetch() {
  fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(response => { fa1(); })
    .catch(err => Bugsnag.notify(err))
}
function fa1() {
  throw new Error("here's an error from fetch() with frames");
}

You'd see frames goFetch(), and fa1() in the stacktrace, but not fb1().

You can store the stack prior to making an async call and augment the stack trace, this article explains this concisely: https://pavelevstigneev.medium.com/capture-javascript-async-stack-traces-870d1b9f6d39. This is what @jmshal was discussing above in PR #242, but this was abandoned (see discussion on PR).

@phillt
Copy link

phillt commented Jan 12, 2022

Fantastic! We've uploaded our src maps and we're already seeing faults in our code. Thank you for your hard work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants