x-error
v0.0.10
Published
Utility for creating and extending error objects
Downloads
2,857
Readme
X-Error
Better JavaScript errors
X-Error expands the error handling capabilities of server-side applications by inhereting and extending the vanilla Error object.
Installation
npm install x-error
Then:
var XError = require('x-error');
Usage
XError([code], [message], [data])
X-Error behaves the same way an Error would, new XError('foo')
is identical to new Error('foo')
. The key difference is that XError provides additional constructor parameters and convenience methods.
You can instantiate X-Error with or without the new keyword, it returns an instance of XError in either case.
Call the constructor with an object to extend its properties:
new XError('hello world', { foo: 'bar', a: 'b' });
Resulting in:
{
message: 'hello world',
foo: 'bar',
a: 'b',
stack: '...'
}
Which is equivalent to calling extend directly:
new XError('hello world').extend({ foo: 'bar', a: 'b' });
And:
new XError().setMessage('hello world').extend({ foo: 'bar', a: 'b' });
Extend instances of Error/XError:
var vanillaError = new Error('hello');
var e = new XError(vanillaError).extend({ to: 'world' });
e.message === vanillaError.message; // true
e.stack === vanillaError.stack; // true
e.to === 'world'; // true
var e2 = new XError(e).extend({ message: 'hi' });
e2.message === vanillaError.message; // false
e2.stack === vanillaError.stack; // true
e2.to === 'world'; // true
Enumeration
Enumerate errors with a code by passing a number as the first argument.
new XError(3000, 'hello world', { foo: 'bar' });
/*
{
code: 3000,
message: 'hello world',
foo: 'bar',
stack: 'Error: hello world ...'
}
*/
HTTP status code & response
One of the most important X-Error features is being able to describe how to handle Errors within the context of HTTP responses.
e.g. using callbacks
User.find(function(err, user) {
if (err) {
return callback(XError(err)
.setHttpCode(400)
.setHttpResponse('Internal error'));
}
if (!user) {
return callback(XError('Unable to find user')
.setHttpCode(400)
.setHttpResponse('Invalid input'));
}
});
Then in your app's route controller/handler:
FooService.doStuff(function(err, result) {
if (err) return res.json(err.httpCode, err.httpResponse);
res.json(200, result);
});
Use shorthands for more terse API calls:
new XError('Server blew up').hc(500).hr('Internal error');
See API for the complete list.
X-Error with Promises
Combine X-Error with promises to create powerful error handlers.
Take a function that returns a promise:
function createFoo() {
return User.find(userId)
.then(function(user){
if (!user) throw XError().hc(400).hr('Invalid input');
return Foo.create({ user: user._id });
})
.catch(function(e) {
// wrap and re-throw
throw XError(e).setSeverity('critical');
});
}
Create an error handler as a function of the res
object:
function createErrHandler(res){
return function(e) {
// do some logging depending on severity
e.severity === 'critical' && logError(e);
res.status(e.httpCode || 500)
.send(e.httpResponse || 'Internal error');
};
}
Call createErrHandler at the end of the promise chain inside your API's route handler
// Foo API
function create(req, res, next) {
createFoo.then(function(foo) {
res.status(200).json(foo);
})
.catch(createErrHandler(req, res));
}
Better JSON support
X-Error is co-operates with JSON.stringify()
by properly enumerating over stack and message properties. This is in contrast with the vanilla Error object which would serialize to an empty object "{}"
.
Better debugging
Use the built-in debug()
method to better diagnose your applications. You can access:
function getStuff(id) {
Stuff.find({ id: id })
.then(function(stuff){
if (!stuff) throw XError().debug(id).hr('oops').hc(400);
return stuff;
});
}
function doThings(req, res) {
getStuff(req.id)
.then(function(stuff){
res.status(200).json(stuff);
})
.catch(function(err){
err.debug(req.body);
// err._debug is now an array containing two items
// which you can log, or do whatever else
logErr(err._debug);
res.status(err.httpCode || 500)
.send(err.httpResponse || 'Internal error');
});
}
API
Convenience methods
| Method | Short Name |
| ------------------------ | -------------- |
| XError.setCode
| XError.c
|
| XError.setMessage
| XError.m
|
| XError.setSeverity
| XError.s
|
| XError.setHttpCode
| XError.hc
|
| XError.setHttpResponse
| XError.hr
|
| XError.extend
| XError.ex
|
| XError.debug
| XError.d
|
Extensible
Since X-Error is a plain JavaScript constructor you can easily extend its prototype to add custom methods for your application:
var XError = require('x-error');
XError.prototype.setPriority = function(priority) {
this.priority = priority;
return this;
};
var e = XError('Update failed')
.setPriority('high')
.debug({ accountId: '123' });
License
Standard MIT License