How to change the default error output in restify
Asked Answered
J

5

11

Is there any way that I can change the default error output? Say I'm going to change the rest error output:

{
    "code": "InvalidArgumentError",
    "message": "blah blah..."
}

to:

{
    "code": 10001,
    "message": "blah blah",
    "extraMsg": "blah blah"
}

Here are some of my ideas:

  • Listen to the error events.
    It seems like not all the RestError have emitted extra events (like NotFound, MethodNotAllowed, VersionNotAllowed... do). So I can't catch all the errors to rewrite them.

  • Listen to an event before response data sent.
    I look through the official documents and have found nothing relative.

  • Modify the implementation of the RestError class.
    Well it's obviously not a good approach.

Any other ideas?

Jube answered 14/5, 2013 at 9:53 Comment(0)
J
11

Finally I provide a customized JSON formatter to get what I want:

var server = restify.createServer( {
    formatters: {
        'application/json': function customizedFormatJSON( req, res, body ) {
            // Copied from restify/lib/formatters/json.js

            if ( body instanceof Error ) {
                // snoop for RestError or HttpError, but don't rely on
                // instanceof
                res.statusCode = body.statusCode || 500;

                if ( body.body ) {
                    body = {
                        code: 10001,
                        scode: body.body.code,
                        msg: body.body.message
                    };
                } else {
                    body = {
                        code: 10001,
                        msg: body.message
                    };
                }
            } else if ( Buffer.isBuffer( body ) ) {
                body = body.toString( 'base64' );
            }

            var data = JSON.stringify( body );
            res.setHeader( 'Content-Length', Buffer.byteLength( data ) );

            return data;
        }
    }
} );
Jube answered 20/5, 2013 at 8:38 Comment(0)
C
5

While the answers above might work, the easiest way to add a custom field to the error body is to call the restify error constructor with an object (hash) instead of a string. The object has to contain the body key which is what you will see in the browser.

For example:

return next(new restify.InvalidArgumentError({body: {field: 'password', message: 'Password has to be at least 6 characters long'}}));

or

return next(new restify.UnauthorizedError({body: {foo: 'bar', name: 'john doe', message: 'whatever error message'}}));
Coranto answered 21/4, 2015 at 13:46 Comment(0)
F
4

Restify offer many ways to implement error management : http://mcavage.github.io/node-restify/#Error-handling

Why don't you create a new error type "myError" just like sample code :

var restify = require('restify');
var util    = require('util');

function MyError(message) {
  restify.RestError.call(this, {
    restCode      : 'MyError',
    statusCode    : 418,
    message       : message,
    constructorOpt: MyError
  });  
  this.name = 'MyError';
}

util.inherits(MyError, restify.RestError);

For common errors I think that overloading methods is not such a bad idea... (I don't speak about modifying restify, just overloading functions using prototype)

(edited)

Fotinas answered 15/5, 2013 at 9:4 Comment(2)
Extending RestError to create new Error Type will not help solve my problem. Maybe I'll try overloading functions using prototype.Thanks!Jube
After a lot of research and some experience with restify I will give this a go as mangling with the formatters seems a bit much lifting.Rostrum
C
1

I was able to provide additional data adding a property to the body object. Notice the this.body.errors = errors line

var restify = require('restify');
var util = require('util');

function ValidationError(message, errors) {
    restify.RestError.call(this, {
        restCode: 'ValidationError',
        statusCode: 400,
        message: message,
        constructorOpt: ValidationError
    });
    this.name = 'ValidationError';
    this.body.errors = errors; //<---
}

util.inherits(ValidationError, restify.RestError);
`
Crossgarnet answered 29/12, 2014 at 18:58 Comment(0)
O
1

You can use restify-errors-options

Your example simply becomes:

const restify = require('restify');
const errors = require('restify-errors');
const errorsOptions = require('restify-errors-options');

errorsOptions.add('extraMsg');
const err = new errors.BadRequestError({extraMsg: 'whatever you want'});

err.toJSON();
//=> {code: 'BadRequest', message: '', extraMsg: 'whatever you want'}

Please also note that the solution provided was only tested on restify 5.x

Follow this issue for more information.

Octans answered 6/8, 2017 at 8:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.