restify-errors

A collection of HTTP and REST Error constructors.
The constructors can be used to new up Error objects with default status codes
set.
The module ships with the following HttpErrors:
- 400 BadRequestError
- 401 UnauthorizedError
- 402 PaymentRequiredError
- 403 ForbiddenError
- 404 NotFoundError
- 405 MethodNotAllowedError
- 406 NotAcceptableError
- 407 ProxyAuthenticationRequiredError
- 408 RequestTimeoutError
- 409 ConflictError
- 410 GoneError
- 411 LengthRequiredError
- 412 PreconditionFailedError
- 413 RequestEntityTooLargeError
- 414 RequesturiTooLargeError
- 415 UnsupportedMediaTypeError
- 416 RangeNotSatisfiableError (For Node >= 4 & iojs >= 3)
- 416 RequestedRangeNotSatisfiableError (For Node 0.x & iojs < 3)
- 417 ExpectationFailedError
- 418 ImATeapotError
- 422 UnprocessableEntityError
- 423 LockedError
- 424 FailedDependencyError
- 425 UnorderedCollectionError
- 426 UpgradeRequiredError
- 428 PreconditionRequiredError
- 429 TooManyRequestsError
- 431 RequestHeaderFieldsTooLargeError
- 500 InternalServerError
- 501 NotImplementedError
- 502 BadGatewayError
- 503 ServiceUnavailableError
- 504 GatewayTimeoutError
- 505 HttpVersionNotSupportedError
- 506 VariantAlsoNegotiatesError
- 507 InsufficientStorageError
- 509 BandwidthLimitExceededError
- 510 NotExtendedError
- 511 NetworkAuthenticationRequiredError
and the following RestErrors:
- 400 BadDigestError
- 405 BadMethodError
- 500 InternalError
- 409 InvalidArgumentError
- 400 InvalidContentError
- 401 InvalidCredentialsError
- 400 InvalidHeaderError
- 400 InvalidVersionError
- 409 MissingParameterError
- 403 NotAuthorizedError
- 412 PreconditionFailedError
- 400 RequestExpiredError
- 429 RequestThrottledError
- 404 ResourceNotFoundError
- 406 WrongAcceptError
Some of the status codes overlap, since applications can choose the most
applicable error type and status code for a given scenario. Should your given
scenario require something more customized, the Error objects can be customized
with an options object.
Getting Started
Install the module with: npm install restify-errors
Usage
Creating Errors
In your application, create errors by using the constructors:
var errors = require('restify-errors');
server.get('/foo', function(req, res, next) {
if (!req.query.foo) {
return next(new errors.BadRequestError());
}
res.send(200, 'ok!');
return next();
});
Checking Error types
You can easily do instance checks against the Error objects:
function redirectIfErr(req, res, next) {
var err = req.data.error;
if (err) {
if (err instanceof errors.InternalServerError) {
next(err);
} else if (err instanceof errors.NotFoundError) {
res.redirect('/NotFound', next);
}
}
}
Rendering Errors
All Error objects in this module are created with a body
property. restify
supports 'rendering' Errors as a response using this property. You can pass
Errors to res.send
and the error will be rendered out as JSON:
function render(req, res, next) {
res.send(new errors.InternalServerError());
return next();
}
Customizing Errors
If you'd like to change the status code or message of a built-in Error, you can
pass an options object to the constructor:
function render(req, res, next) {
var myErr = new errors.InvalidVersionError({
statusCode: 409,
message: 'Version not supported with current query params'
});
res.send(myErr);
return next();
}
Passing in prior errors (causes)
Like WError, all constructors
accept an Error object as the first argument to build rich Error objects and
stack traces. Assume a previous file lookup failed and an error was passed on:
function wrapError(req, res, next) {
if (req.error) {
var myErr = new errors.InternalServerError(req.error, 'bad times!');
return next(myErr);
}
return next();
}
This will allow Error objects to maintain context from previous errors, giving
you full visibility into what caused an underlying issue:
console.log(myErr.message);
console.log(myErr.toString());
bunyanLogger.info(myErr);
InternalServerError: bad times!
at Object.<anonymous> (/Users/restify/test.js:30:16)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Caused by: Error: file lookup failed!
at Object.<anonymous> (/Users/restify/test.js:29:15)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Bunyan support
Since errors created via restify-errors inherit from VError, you'll get out of
the box support via bunyan's standard serializers. If you are using the
context
property, you can use the serializer shipped with restify-errors:
var bunyan = require('bunyan');
var restifyErrors = require('restify-errors');
var log = bunyan.createLogger({
name: 'myLogger',
serializers: {
err: restifyErrors.bunyanSerializer
}
});
var err = new restifyErrors.InternalServerError({
message: 'cannot service this request!',
context: {
foo: 'bar',
bar: 1
}
});
log.error(err, 'oh noes');
[2016-08-31T22:27:13.117Z] ERROR: log/51633 on laptop: oh noes (err.code=InternalServer)
InternalServerError: cannot service this request! (foo="bar", bar=1)
at Object.<anonymous> (/restify/test.js:11:11)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3
You can, of course, combine this with the standard set of serializers that
bunyan ships with.
VError support
This serializer also comes with support for VError's new info
property:
var err = new VError({
name: 'BoomError',
info: {
foo: 'bar',
baz: 1
}
}, 'something bad happened!');
log.error(err, 'oh noes');
[2016-08-31T22:21:35.900Z] ERROR: log/50874 on laptop: oh noes
BoomError: something bad happened! (foo="bar", baz=1)
at Object.<anonymous> (/restify/test.js:11:11)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3
VError's MultiError is also supported:
var underlyingErr = new Error('boom');
var multiErr = new verror.MultiError([
new Error('boom'),
new restifyErrors.InternalServerError(underlyingErr, {
message: 'wrapped',
context: {
foo: 'bar',
baz: 1
}
})
]);
log.error(multiErr, 'oh noes');
[2016-08-31T22:48:43.244Z] ERROR: logger/55311 on laptop: oh noes
MultiError 1 of 2: Error: boom
at Object.<anonymous> (/restify/test.js:16:5)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3
MultiError 2 of 2: InternalServerError: wrapped (foo="bar", baz=1)
at Object.<anonymous> (/restify/test.js:17:5)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3
Caused by: Error: boom
at Object.<anonymous> (/restify/test.js:14:21)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3
For more information about building rich errors, check out
VError.
Subclassing Errors
You can also create your own Error subclasses by using the provided
makeConstructor()
method. Making a new subclass will add the constructor to
the existing exports object:
errors.makeConstructor('ExecutionError', {
statusCode: 406,
failureType: 'motion'
});
var myErr = new errors.ExecutionError('bad joystick input!');
console.log(myErr instanceof ExecutionError);
console.log(myErr.message);
console.log(myErr.failureType);
console.log(myErr.statusCode);
console.log(myErr.stack);
ExecutionError: bad joystick input!
at Object.<anonymous> (/Users/restify/test.js:30:16)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Custom errors are subclassed from RestError, so you get all the built-in
goodness of HttpError/RestError. The constructor returned to you accepts
all the same signatures accepted by HttpError/RestError.
API
All error constructors are variadic and accept the following signatures:
new Error(message)
new Error(printf, args...)
new Error(options [, printf, args...])
new Error(priorErr, message])
new Error(priorErr [, printf, args...])
new Error(priorErr, options [, printf, args...])
All VError and WError signatures
are also supported, including
extsprintf.
You can pass in a message like a regular error:
message
{String} - an error message
Or pass in an options object for more customization:
options.message
{String} - an error message stringoptions.statusCode
{Number} - an http status codeoptions.restCode
{Number} - a description code for your Error. This is used
by restify to render an error when it is directly passed to res.send()
. By
default, it is the name of your error constructor (e.g., the restCode for a
BadDigestError is BadDigest).options.context
{Object} - object of contextual properties relevant to the
creation of the error, i.e., the url of a failed http request
In all signatures, you can optionally pass in an Error as the first argument,
which will cause WError to use it as a prior cause:
priorErr
{Error} - an Error object
Returns: {Error} an Error object
IMPORTANT: If a printf style signature is used, the Error message will
prefer that over options.message
.
makeConstructor(name [, defaults])
Creates a custom Error constructor, adds it to the existing exports object.
name
{String} - the name of your Errordefaults
{Object} - an object of default values that will added to the
prototype. It is possible to override the default toString()
and toJSON()
methods.
Returns: {void}
makeErrFromCode(name [, args...])
Create an Error object using an http status code. This uses http
module's
STATUS_CODES
to do the status code lookup. Thus, this convenience method
is useful only for creating HttpErrors, and not RestErrors.
statusCode
{Number} - an http status codeargs
- arguments to be passed on to the constructor
Returns: {Object} an Error object
Contributing
Add unit tests for any new or changed functionality. Ensure that lint and style
checks pass.
To start contributing, install the git pre-push hooks:
make githooks
Before committing, run the prepush hook:
make prepush
If you have style errors, you can auto fix whitespace issues by running:
make codestyle-fix
License
Copyright (c) 2015 Alex Liu
Licensed under the MIT license.