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

Improve logging and available information when error reports are not sent #515

Merged
merged 9 commits into from
Apr 12, 2019

Conversation

bengourley
Copy link
Contributor

This PR contains a few small improvements for the following situations:

  • releaseStage is not in the list of notifyReleaseStages, therefore reports are not send
  • a beforeSend callback prevents a report from being sent

The problem

As described in #449, Bugsnag shouldn't silently consume the errors if it's not going to send them anywhere, they should be logged out.

Unhandled errors

In both of these cases, when the error is unhandled the following log message would be written and the notify(err, opts, cb) callback would not run:

[bugsnag] Report not sent due to releaseStage/notifyReleaseStages configuration

By ensuring that the notify(err, opts, cb) callback is called, in Node this means the defautlt onUncaughtException (and onUnhandledRejection) now correctly get called so the error is printed and the process exits (using the example from #449):

[bugsnag] Report not sent due to releaseStage/notifyReleaseStages configuration
[bugsnag] Uncaught exception, the process will now terminate…
/Users/bengourley/scratch/bad.js:2
  bad: 123;
          ^

SyntaxError: Unexpected token ;
    at new Script (vm.js:74:7)
    at createScript (vm.js:246:10)
    at Object.runInThisContext (vm.js:298:10)
    at Module._compile (internal/modules/cjs/loader.js:670:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
    at Module.load (internal/modules/cjs/loader.js:612:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
    at Function.Module._load (internal/modules/cjs/loader.js:543:3)
    at Module.require (internal/modules/cjs/loader.js:650:17)
    at require (internal/modules/cjs/helpers.js:20:18)

Unit tests were added to ensure the behaviour was correct for various permutations.

Handled errors

The situation for handled errors is a little different. We can't assume that a log is desirable, but we can provide the means for users to log it themselves.

I added a property originalError to the Report class which contains whatever the raw thing was that the report was created from. This also resolves #420, meaning that users who want to do something such as

  • log out the stack
  • inspect the error

can do so with the following:

// it's available in beforeSend, however if the beforeSend callback was
// added after one which can return false, this one won't be run
bugsnagClient.notify(new Error, {
  beforeSend: report => console.log(report.originalError)
})

// so it's also in the notify callback which runs after the last
// beforeSend, even if one returned false
bugsnagClient.notify(new Error, { /* opts */ }, (err, report) => {
  console.log(report.originalError)
})

Tests

Added unit tests to ensure the client.notify(err, opts, cb) callback was always called. The end-to-end tests aren't set up to make assertions about the the process's output, so I manually tested that the expected content was seen when releaseStage was not in notifyReleaseStages and when a beforeSend prevented a report from sending.

Bundle size discussion time

Since this makes changes to @bugsnag/core it stands to affect browser bundle size. Here's the change:

- 11.68kB
+ 11.69kB

Net increase of 0.01kB. I think this is 🆗.

In the following circumstances, the notify callback wasn't called:

- report not sent due to
releaseStage/notifyReleaseStages config
- report not sent due to beforeSend callback

This meant
that the configured onUncaughtException and onUnhandledRejection callbacks (in Node) were never
called, and so unhandled errors were effectively silently swallowed. Although intentionally not
reported, it's still useful to know about so this change ensures the callbacks run. The types were
updated to remove the no-longer present notion that the the return value of notify() indicated
whether the report was sent or not.

Fixes #449
This log can be preceded by "[bugsnag] Report not sent due to releaseStage/notifyReleaseStages
configuration" so it's misleading to say that it was reported. Removing the verb completely makes it
correct and retains enough meaning.
errorMessage: string,
stacktrace?: any[],
handledState?: IHandledState,
originalError?: any,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some docs or usage/tests to go along with this change?

Copy link
Contributor Author

@bengourley bengourley Apr 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured I would write the docs once the implementation was ratified. I don't have a good reason for not adding tests for that aspect of this PR though so I will add some.

@bengourley bengourley merged commit cd0b919 into next Apr 12, 2019
@bengourley bengourley deleted the notify-release-stage-swallowing branch April 12, 2019 11:32
@mattdyoung mattdyoung mentioned this pull request Nov 28, 2019
@jordyvandomselaar
Copy link

Is there any chance this could be added to the JS docs? I couldn't find it in there =), thanks for the originalError addition! It has helped us a lot with grouping errors etc.

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

Successfully merging this pull request may close these issues.

v4 - access to original exception in beforeSend
3 participants