errorhandler
Development-only error handler middleware.
This middleware is only intended to be used in a development environment, as
the full error stack traces and internal details of any object passed to this
module will be sent back to the client when an error occurs.
When an object is provided to Express as an error, this module will display
as much about this object as possible, and will do so by using content negotiation
for the response between HTML, JSON, and plain text.
- When the object is a standard
Error
object, the string provided by the
stack
property will be returned in HTML/text responses. - When the object is a non-
Error
object, the result of
util.inspect
will be returned in HTML/text responses. - For JSON responses, the result will be an object with all enumerable properties
from the object in the response.
Install
This is a Node.js module available through the
npm registry. Installation is done using the
npm install
command:
$ npm install errorhandler
API
var errorhandler = require('errorhandler')
errorhandler(options)
Create new middleware to handle errors and respond with content negotiation.
Options
Error handler accepts these properties in the options object.
log
Provide a function to be called with the error and a string representation of
the error. Can be used to write the error to any desired location, or set to
false
to only send the error back in the response. Called as
log(err, str, req, res)
where err
is the Error
object, str
is a string
representation of the error, req
is the request object and res
is the
response object (note, this function is invoked after the response has been
written).
The default value for this option is true
unless process.env.NODE_ENV === 'test'
.
Possible values:
true
: Log errors usingconsole.error(str)
.false
: Only send the error back in the response.- A function: pass the error to a function for handling.
Examples
Simple example
Basic example of adding this middleware as the error handler only in development
with connect
(express
also can be used in this example).
var connect = require('connect') var errorhandler = require('errorhandler') var app = connect() if (process.env.NODE_ENV === 'development') { // only use in development app.use(errorhandler()) }
Custom output location
Sometimes you may want to output the errors to a different location than STDERR
during development, like a system notification, for example.
var connect = require('connect') var errorhandler = require('errorhandler') var notifier = require('node-notifier') var app = connect() if (process.env.NODE_ENV === 'development') { // only use in development app.use(errorhandler({ log: errorNotification })) } function errorNotification (err, str, req) { var title = 'Error in ' + req.method + ' ' + req.url notifier.notify({ title: title, message: str }) }
License
MIT
- body-parser
- compression
- connect-rid
- cookie-parser
- cookie-session
- cors
- errorhandler
- method-override
- morgan
- multer
- response-time
- serve-favicon
- serve-index
- serve-static
- session
- timeout
- vhost
Development-only error handler middleware.
This middleware is only intended to be used in a development environment, as
the full error stack traces and internal details of any object passed to this
module will be sent back to the client when an error occurs.
When an object is provided to Express as an error, this module will display
as much about this object as possible, and will do so by using content negotiation
for the response between HTML, JSON, and plain text.
- When the object is a standard
Error
object, the string provided by the
stack
property will be returned in HTML/text responses. - When the object is a non-
Error
object, the result of
util.inspect
will be returned in HTML/text responses. - For JSON responses, the result will be an object with all enumerable properties
from the object in the response.
Install
This is a Node.js module available through the
npm registry. Installation is done using the
npm install
command:
$ npm install errorhandler
API
var errorhandler = require('errorhandler')
errorhandler(options)
Create new middleware to handle errors and respond with content negotiation.
Options
Error handler accepts these properties in the options object.
log
Provide a function to be called with the error and a string representation of
the error. Can be used to write the error to any desired location, or set to
false
to only send the error back in the response. Called as
log(err, str, req, res)
where err
is the Error
object, str
is a string
representation of the error, req
is the request object and res
is the
response object (note, this function is invoked after the response has been
written).
The default value for this option is true
unless process.env.NODE_ENV === 'test'
.
Possible values:
true
: Log errors usingconsole.error(str)
.false
: Only send the error back in the response.- A function: pass the error to a function for handling.
Examples
Simple example
Basic example of adding this middleware as the error handler only in development
with connect
(express
also can be used in this example).
var connect = require('connect')
var errorhandler = require('errorhandler')
var app = connect()
if (process.env.NODE_ENV === 'development') {
// only use in development
app.use(errorhandler())
}
Custom output location
Sometimes you may want to output the errors to a different location than STDERR
during development, like a system notification, for example.
var connect = require('connect')
var errorhandler = require('errorhandler')
var notifier = require('node-notifier')
var app = connect()
if (process.env.NODE_ENV === 'development') {
// only use in development
app.use(errorhandler({ log: errorNotification }))
}
function errorNotification (err, str, req) {
var title = 'Error in ' + req.method + ' ' + req.url
notifier.notify({
title: title,
message: str
})
}
License
MIT
Github repository
Why do we need error handling at all?
Imagine that a client application (web, mobile…) is using the server. Sometimes we need to handle exceptions which appear in the application and we need to send a clear message to the user what is wrong. It is very important to have a working error handler inside the application in order to achieve better user experience and for many other reasons as well. Beside from the user experience, it is a good practice to catch errors in one place (all the errors go through the handler) so the developer can track the bugs/exceptions more easily.
Creating exceptions
An exception is created using the throw
keyword inside the application.
throw Error('Error');
Enter fullscreen mode
Exit fullscreen mode
As soon as the application executes this line the normal flow is halted and the control is switched to the nearest exception handler. While in some other environments we can throw strings, objects etc, in Node.js we throw error objects
. An error object is an object derived from Error
or an instance of Error
itself.
Throwing an error from derived Error
object looks like:
class SomethingIsWrongError extends Error {
constructor() {
super('Something is wrong!');
}
}
throw new SomethingIsWrongError();
Enter fullscreen mode
Exit fullscreen mode
Before we start creating our error handler we need to decide what is the right way to go. Most of my applications have supported/support multiple languages which means that the message needs to be translated into the language which the user has selected. We cannot show errors in English language if the user has selected Japanese language which means the error message needs to be translated somewhere. Either we translate the message on the server side or on the client side.
-
Server side translation
In order to translate the message on the server side we have to know to whom we are sending the exception in order to get the selected language from the user. Challenge of this approach is that a developer needs always to have the selected language of the user whenever an error message needs to be sent to the client side. -
Client side translation
Other solution is to send an unique error code and any additional data if needed so the translation of exceptions should be done on the client side based on the code and this is the solution which I prefer.
The client side needs to know:
- Status code.
- Unique error code. Every error has its own unique code.
- Metadata if any. If any additional dynamic data needs to be sent in order to translate the message like what is the maximum allowed input number etc.
In order to keep track of all the errors more easily, we need to create a class in which we will store all possible errors that we know about. When we throw an exception then we will refer to one of the codes found in that class.
Create a folder called error-handler
in the root directory and this will be the place where we will create files for error handler logic. Create a file called error-code.ts
with following code:
export class ErrorCode {
public static readonly Unauthenticated = 'Unauthenticated';
public static readonly NotFound = 'NotFound';
public static readonly MaximumAllowedGrade = 'MaximumAllowedGrade';
public static readonly AsyncError = 'AsyncError';
public static readonly UnknownError = 'UnknownError';
}
Enter fullscreen mode
Exit fullscreen mode
We also need to have a model that we will return to the client. Create a file called error-model.ts
inside error-handler
folder with following code:
export class ErrorModel {
/**
* Unique error code which identifies the error.
*/
public code: string;
/**
* Status code of the error.
*/
public status: number;
/**
* Any additional data that is required for translation.
*/
public metaData?: any;
}
Enter fullscreen mode
Exit fullscreen mode
And now we need to create the actual error exception object. Create a file called error-exception.ts
inside error-handler
folder with following code:
import { ErrorCode } from './error-code';
export class ErrorException extends Error {
public status: number = null;
public metaData: any = null;
constructor(code: string = ErrorCode.UnknownError, metaData: any = null) {
super(code);
Object.setPrototypeOf(this, new.target.prototype);
this.name = code;
this.status = 500;
this.metaData = metaData;
switch (code) {
case ErrorCode.Unauthenticated:
this.status = 401;
break;
case ErrorCode.MaximumAllowedGrade:
this.status = 400;
break;
case ErrorCode.AsyncError:
this.status = 400;
break;
case ErrorCode.NotFound:
this.status = 404;
break;
default:
this.status = 500;
break;
}
}
}
Enter fullscreen mode
Exit fullscreen mode
When we want to throw an error from our application we use exactly the class we created and one code from the available list of codes. We would throw an error like:
throw new ErrorException(ErrorCode.MaximumAllowedGrade, { max: 100 }); // object is optional
Enter fullscreen mode
Exit fullscreen mode
Error handler
Error handler is a special middleware in Node.js which takes 4 parameters. Regular route middleware takes 3 parameters: req, res and next. Error handler also takes these 3 parameters and one additional parameter which is the actual error. Those four parameters are (retrospectively):
- err
- req
- res
- next
Create file called error-handler.ts
inside error-handler
folder. The following handler will intercept all errors that occur in the application whether it is an exception that we know or an exception that we do not know. In order to recognize that it is an exception thrown by ourselves, we can recognize it by type of instance if (err instanceof ErrorException)
import { Request, Response, NextFunction } from 'express';
import { ErrorCode } from './error-code';
import { ErrorException } from './error-exception';
import { ErrorModel } from './error-model';
export const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction) => {
console.log('Error handling middleware called.');
console.log('Path:', req.path);
console.error('Error occured:', err);
if (err instanceof ErrorException) {
console.log('Error is known.');
res.status(err.status).send(err);
} else {
// For unhandled errors.
res.status(500).send({ code: ErrorCode.UnknownError, status: 500 } as ErrorModel);
}
};
Enter fullscreen mode
Exit fullscreen mode
Now it is necessary to register this handler and we will register it as follows. The handler needs to be ‘lowered’ as far as possible in the application after all routes and other middlewares and handlers. If we specify routes or middlewares after registration of errorHandler
then the error handler will not catch exceptions which appear in those routes or middlewares.
app.use(errorHandler); // registration of handler
app.listen(3000, () => {
console.log('Application started on port 3000!');
});
Enter fullscreen mode
Exit fullscreen mode
Now we are ready to throw some errors.
app.get('/throw-unauthenticated', (req: Request, res: Response, next: NextFunction) => {
throw new ErrorException(ErrorCode.Unauthenticated);
// or
// next(new ErrorException(ErrorCode.Unauthenticated))
});
app.get('/throw-maximum-allowed-grade', (req: Request, res: Response, next: NextFunction) => {
throw new ErrorException(ErrorCode.MaximumAllowedGrade, { grade: Math.random() });
// or
// next(new ErrorException(ErrorCode.MaximumAllowedGrade, { grade: Math.random() }))
});
app.get('/throw-unknown-error', (req: Request, res: Response, next: NextFunction) => {
const num: any = null;
// Node.js will throw an error because there is no length property inside num variable
console.log(num.length);
});
Enter fullscreen mode
Exit fullscreen mode
If you look at the code above, you will see that we have 2 known
exceptions and one unknown
. When we want to throw an exception from a route we can do it with the throw
keyword or by calling the next
function with an actual exception. Error handler will catch both exceptions. However, when it comes to async logic then it will be solved in another way which we will cover next.
Exceptions with promises
By Exress documentation:
Handling sync code:
Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it. For example:
app.get('/', function (req, res) {
throw new Error('BROKEN'); // Express will catch this on its own.
});
Enter fullscreen mode
Exit fullscreen mode
Handling async code:
For errors returned from asynchronous functions invoked by route handlers and middleware, you must pass them to the next() function, where Express will catch and process them. For example:
app.get('/', function (req, res, next) {
fs.readFile('/file-does-not-exist', function (err, data) {
if (err) {
next(err); // Pass errors to Express.
} else {
res.send(data);
}
});
});
Enter fullscreen mode
Exit fullscreen mode
Starting with Express 5, route handlers and middleware that return a Promise will call next(value) automatically when they reject or throw an error. For example:
app.get('/user/:id', async function (req, res, next) {
// if error appears in getUserById, express will automatically throw an error
const user = await getUserById(req.params.id);
res.send(user);
});
Enter fullscreen mode
Exit fullscreen mode
Let’s add code into our application for async code. The code will always throw an error and regarding if we are using express 4 or express 5, the application will catch the error.
const someOtherFunction = () => {
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new ErrorException(ErrorCode.AsyncError));
}, 1000);
});
return myPromise;
};
app.get('/throw-async-await-error', async (req: Request, res: Response, next: NextFunction) => {
// express 4
try {
await someOtherFunction();
} catch (err) {
next(err);
// next line will not work as expected
// throw err
}
// express 5
// await someOtherFunction();
});
Enter fullscreen mode
Exit fullscreen mode
Wrapping up
In this tutorial we covered what exceptions are and how to throw an exception in application. We learned what we need to consider when handling exceptions in multi language applications. We learned to do everything necessary for the Node.JS application to successfully manage exceptions from creating necessary classes to creating a handler and registering it. And finally we learned how to throw exceptions and what to take care of when throwing exceptions in async or sync blocks.
Comming up: Authentication with JWT.
Weekly Downloads (1,187,440)
- GitHub Stars
-
410
- Forks
-
60
- Contributors
-
6
Direct Usage Popularity
The npm package errorhandler receives a total of
1,187,440 downloads a week. As such, we scored
errorhandler popularity level to be Influential project.
Based on project statistics from the GitHub repository for the
npm package errorhandler, we found that it has been
starred 410 times.
Downloads are calculated as moving averages for a period of the last 12
months, excluding weekends and known missing data points.
Commit Frequency
- Open Issues
- 0
- Open PR
- 0
- Last Release
-
4 years ago
- Last Commit
-
3 years ago
Further analysis of the maintenance status of errorhandler based on
released npm versions cadence, the repository activity,
and other data points determined that its maintenance is
Sustainable.
An important project maintenance signal to consider for errorhandler is
that it
hasn’t seen any new versions released to npm in the
past 12 months, and could be considered as a discontinued project, or that which
receives low attention from its maintainers.
In the past month we didn’t find any pull request activity or change in
issues status has been detected for the GitHub repository.
- Node.js Compatibility
-
>= 0.8
- Age
-
9 years
- Dependencies
-
2 Direct
- Versions
-
24
- Install Size
-
15.2 kB
- Dist-tags
-
1
- # of Files
-
7
- Maintainers
-
5
- TS Typings
-
Yes
errorhandler has more than a single and default latest tag published for
the npm package. This means, there may be other tags available for this
package, such as next to indicate future releases, or stable to indicate
stable releases.