By default Feathers just uses the default error handler that comes with Express. It's pretty basic so the feathers-errors module comes bundled with a more robust error handler that you can use in your app. This error handler is the one that is included in a generated Feathers app by default.
ProTip: Because Feathers extends Express you can use any Express compatible error middleware with Feathers. In fact, the error handler bundled with
feathers-errors
is just a slightly customized one.
Many Feathers plugins (like the database adapters and authentication) already throw Feathers errors, which include their status codes. The default error handler sends a JSON representation of the error (without the stacktrace in production) or sends a default 404.html
or 500.html
error page when visited in the browser.
If you want to use your own custom error pages you can do with a custom HTML formatter like this:
const error = require('feathers-errors/handler');
const app = feathers();
// Just like Express your error middleware needs to be
// set up last in your middleware chain.
app.use(error({
html: function(error, req, res, next) {
// render your error view with the error object
res.render('error', error);
}
}))
ProTip: If you want to have the response in json format be sure to set the
Accept
header in your request toapplication/json
otherwise the default error handler will return HTML.
The following options can be passed when creating a new localstorage service:
html
(Function|Object) [optional] - A custom formatter function or an object that contains the path to your custom html error pages.
ProTip:
html
can also be set tofalse
to disable html error pages altogether so that only JSON is returned.
Promises swallow errors if you forget to add a catch()
statement. Therefore, you should make sure that you always call .catch()
on your promises. To catch uncaught errors at a global level you can add the code below to your top-most file.
process.on('unhandledRejection', (reason, p) => {
console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
});
feathers-errors
currently provides the following error types, all of which are instances of FeathersError
:
ProTip: All of the feathers plugins will automatically emit the appropriate Feathers errors for you.
BadRequest
: 400NotAuthenticated
: 401PaymentError
: 402Forbidden
: 403NotFound
: 404MethodNotAllowed
: 405NotAcceptable
: 406Timeout
: 408Conflict
: 409Unprocessable
: 422GeneralError
: 500NotImplemented
: 501Unavailable
: 503
Feathers errors are pretty flexible. They contain the following fields:
type
-FeathersError
name
- The error name (ie. "BadRequest", "ValidationError", etc.)message
- The error message stringcode
- The HTTP status codeclassName
- A CSS class name that can be handy for styling errors based on the error type. (ie. "bad-request" , etc.)data
- An object containing anything you passed to a Feathers error except for theerrors
object.errors
- An object containing whatever was passed to a Feathers error insideerrors
. This is typically validation errors or if you want to group multiple errors together.
Here are a few ways that you can use them:
const errors = require('feathers-errors');
// If you were to create an error yourself.
const notFound = new errors.NotFound('User does not exist'));
// You can wrap existing errors
const existing = new errors.GeneralError(new Error('I exist'));
// You can also pass additional data
const data = new errors.BadRequest('Invalid email', {email: '[email protected]'});
// You can also pass additional data without a message
const dataWithoutMessage = new errors.BadRequest({email: '[email protected]'});
// If you need to pass multiple errors
const validationErrors = new errors.BadRequest('Invalid Parameters', {errors: {email: 'Email already taken'} });
// You can also omit the error message and we'll put in a default one for you
const validationErrors = new errors.BadRequest({errors: {email: 'Invalid Email'} });