Node.js Error & Exception Tracking
Typical installation time: 3 minutes
Hi there! You've found Honeybadger's guide to Node.js error and exception tracking. Once installed, Honeybadger will automatically report errors from your Node.js application.
Heads up! Between callbacks, promises, event emitters, and timers, error-handling in Node.js is a complex and difficult field, but we're here to help! Our Node.js library tries to catch as many different kinds of errors as possible with minimal configuration; if you encounter problems setting it up or find any gaps, feel free to open an issue.
Installation
First, install the npm package:
npm install @honeybadger-io/js --save
Then, require the honeybadger module and configure your API key:
const Honeybadger = require('@honeybadger-io/js');
Honeybadger.configure({
apiKey: '[ YOUR API KEY HERE ]'
});
By default Honeybadger will be notified automatically of all unhandled errors which crash your node processes. Many applications catch errors, however, so you may want to set up some additional framework integrations.
Framework integrations
Express and Express-style frameworks
Errors which happen in Express or Connect apps can be automatically reported to Honeybadger by installing our middleware.
The requestHandler
middleware must be added before your other app middleware, while the errorHandler
must be added after all app middleware and routes, but before any custom error handling middleware:
app.use(Honeybadger.requestHandler); // Use *before* all other app middleware.
// Any other middleware and routes
app.use(myMiddleware);
app.get("/", (req, res) => {...});
app.use(Honeybadger.errorHandler); // Use *after* all other app middleware
// Your custom error handling middleware
app.use(myErrorMiddleware);
You can follow a similar pattern for most frameworks which use Express-style middleware:
Restify
const server = restify.createServer();
server.use(Honeybadger.requestHandler);
// Other middleware and routes...
server.on('restifyError', Honeybadger.errorHandler);
Sails.js
For Sails.js, use Honeybadger.errorHandler
to report errors from within your custom serverError
response.
const Honeybadger = require('@honeybadger-io/js');
module.exports = function serverError(optionalData) {
if (_.isError(optionalData)) {
Honeybadger.errorHandler(optionalData, this.req);
return res.status(500).send(optionalData.stack);
}
};
You should also add the Honeybadger.requestHandler
at the start of your middleware chain so asynchronous context can be correctly tracked between requests:
// in config/http.js
module.exports.http = {
middleware: {
order: [
'honeybadgerContext',
// other middleware...
],
honeybadgerContext: Honeybadger.requestHandler,
},
};
Non-Express-style frameworks
For frameworks that don't use Express-style middleware, Honeybadger will still capture unhandled exceptions automatically, but you may need to add a few lines of code to capture other kinds of errors and use the context feature properly. See the section on Tracking Context below.
AWS Lambda
To automatically report errors which happen in your AWS Lambda functions, wrap your Lambda handlers in Honeybadger.lambdaHandler()
:
async function myHandler(event, context) {
// ...
}
exports.handler = Honeybadger.lambdaHandler(myHandler);
Check out our example AWS Lambda project for a list of handlers with different settings.
Timeout Warning
If your Lambda function hits its time limit, it will get killed by AWS Lambda without completing. Honeybadger can notify you when your function is about time out. By default, this will be when there are only 50 milliseconds left to reach the limit. You can override this with the timeoutWarningThresholdMs
setting:
Honeybadger.configure({
timeoutWarningThresholdMs: 1000
});
You can disable the timeout warning with the reportTimeoutWarning
setting:
Honeybadger.configure({
reportTimeoutWarning: false
});
To manually report errors in a serverless environment, use Honeybadger.notifyAsync
. Read more below.
Manually Reporting Errors
Honeybadger reports unhandled exceptions by default. You can also manually notify Honeybadger of errors and other events in your application code:
try {
// ...error producing code...
} catch(error) {
Honeybadger.notify(error);
}
Honeybadger.notify
implements a fire-and-forget approach, which means that you can call the function
and continue execution in your application code without waiting for the error to be reported.
This is OK for most applications, but in some environments this can cause problems when the execution environment
could be terminated before the report is sent to Honeybadger. For this reason, you may use Honeybadger.notifyAsync
which
is a promise-based implementation of notify
and will resolve only after the report is sent:
async function doSomething() {
try {
// ...error producing code...
} catch(error) {
await Honeybadger.notifyAsync(error);
}
}
See the full documentation for more options.
Tracking Context
You can add contextual information to your error reports to make debugging easier:
Honeybadger.setContext({
query: searchQuery,
});
When an error is captured (manually or automatically), the context will be sent along in the error report and displayed in the Context section of the Honeybadger UI.
Important: in apps like web servers that handle multiple requests at the same time, you need to properly isolate each request's context.
For middleware-based frameworks like Express, this is done automatically when you use the requestHandler
middleware. For other frameworks, you'll need to wrap your request and error handlers in Honeybadger.withRequest()
method and pass in the request object. Here are examples in some popular frameworks:
Fastify
Fastify doesn't support middleware by default, but you can use the preHandler
hook instead. You'll also need to add a custom error handler (and be sure to wrap it in Honeybadger.withRequest
):
fastify.addHook('preHandler', Honeybadger.requestHandler);
fastify.setErrorHandler((err, req, reply) => Honeybadger.withRequest(req, () => {
Honeybadger.notify(err);
reply.send({message: "error"})
}));
AdonisJS
For AdonisJS, you'll need to do three (easy) steps:
- Create a middleware that wraps your request handlers with
withRequest()
). You can generate a middleware withadonis make:middleware HoneybadgerContext
(v4) ornode ace make:middleware HoneybadgerContext
(v5):
// Adonis v4: app/Middleware/HoneybadgerContext.js
// Adonis v5: app/Middleware/HoneybadgerContext.ts
class HoneybadgerContext {
async handle ({ request, response }, next) {
await Honeybadger.withRequest(request, next)
}
}
- Register the middleware:
// Adonis v4: in start/kernel.js
const globalMiddleware = [
'App/Middleware/HoneybadgerContext'
]
// Adonis v5: in start/kernel.ts
Server.middleware.register([
() => import('App/Middleware/HoneybadgerContext'),
])
- In your exception handler's
report()
method, make sure to usewithRequest()
. (On Adonis v4, you may need to generate an exception handler withadonis make:ehandler
):
// Adonis v4: app/Exceptions/Handler.js
// Adonis v5: app/Exceptions/Handler.ts
class ExceptionHandler extends BaseExceptionHandler {
// ...
async report (error, { request }) {
Honeybadger.withRequest(request, () => Honeybadger.notify(error))
}
}
Hapi
In Hapi, you'll need to wrap your request handlers in withRequest
, as well as add an onPreResponse
extension to report errors.
server.route({
method: 'POST',
path: '/search',
handler: async (request, h) => Honeybadger.withRequest(request, () => {
Honeybadger.setContext({ query: request.payload.searchQuery });
return ...;
})
});
server.ext('onPreResponse', (request, h) => Honeybadger.withRequest(request, () => {
if (!request.response.isBoom) {
return h.continue;
}
Honeybadger.notify(request.response);
return h.continue;
}));
Identifying Users
Honeybadger can track what users have encountered each error. To identify the
current user in error reports, add a user identifier and/or email address with
Honeybadger.setContext
:
Honeybadger.setContext({
user_id: 123,
user_email: 'user@example.com'
});
We'll surface this info in a special "Affected Users" section in the Honeybadger UI.
Tracking Deploys
Honeybadger can also keep track of application deployments, and link errors to
the version which the error occurred in. Here's a simple curl
script to record
a deployment:
HONEYBADGER_ENV="production" \
HONEYBADGER_REVISION="git SHA/project version" \
HONEYBADGER_API_KEY="Your project API key" \
curl -g "https://api.honeybadger.io/v1/deploys?deploy[environment]=$HONEYBADGER_ENV&deploy[local_username]=$USER&deploy[revision]=$HONEYBADGER_REVISION&api_key=$HONEYBADGER_API_KEY"
Be sure that the same revision is also configured in the honeybadger.js library. Read more about deploy tracking in the API docs.
Uncaught Exceptions
Honeybadger's default uncaught exception handler logs the error and exits the
process after notifying Honeybadger of the uncaught exception. You can change
the default handler by replacing the afterUncaught
config callback with a
new handler function. Honeybadger will still be notified before your handler
is invoked. Note that it's important to exit the process cleanly if you
replace the handler; see Warning: using 'uncaughtException'
correctly
for additional information.
Examples
Honeybadger.configure({
afterUncaught: (err) => {
doSomethingWith(err);
process.exit(1);
}
});
Disable Honeybadger's uncaught error handler
To disable Honeybadger's handler entirely (restoring Node's default behavior for uncaught exceptions), use the enableUncaught
option when calling Honeybadger.configure
:
Honeybadger.configure({
apiKey: '[ YOUR API KEY HERE ]'
enableUncaught: false
});
Source Map Support
Honeybadger can automatically un-minify your code if you provide a source map along with your minified JavaScript files. See our Source Map Guide for details.
Honeybadger also supports Node's experimental --source-map-support
flag as of version 14+. If you run node
with --source-map-support
(and are generating source maps in your build), your stack traces should be automatically translated before they are sent to Honeybadger.
Sample Application
If you'd like to see the library in action before you integrate it with your apps, check out our sample Node.js/Express application.
You can deploy the sample app to your Heroku account by clicking this button:
Don't forget to destroy the Heroku app after you're done so that you aren't charged for usage.
The code for the sample app is available on Github, in case you'd like to read through it, or run it locally.
Package:
@honeybadger-io/js
Version:
6.10.0
Repository:
https://github.com/honeybadger-io/honeybadger-js/tree/master/packages/js