Error handling in Restify

1,871 views
Skip to first unread message

Dave Artz

unread,
Mar 7, 2014, 8:02:23 PM3/7/14
to res...@googlegroups.com
According to the docs:

You can handle errors in restify a few different ways. First, you can always just call res.send(err). You can also shorthand this in a route by doing:

server.get('/hello/:name', function(req, res, next) {
  return database.get(req.params.name, function(err, user) {
    if (err)
      return next(err);

    res.send(user);
    return next();
  });
});

I have the following code:

var restify = require('restify');
var server = restify.createServer();

server.get('/error', function (req, res, next) {
var err = { 'error': 'I did a bad thing.', statusCode: 500 };
if (err) {
return next(err);
}
});

server.listen(3001);

When I run this and hit the /error route, Restify does not send the response to the browser - it just hangs out.

The docs imply that Restify will automagically do a res.send() with my error.

I'm wondering if this is as designed or if I'm missing something obvious.

Thanks!
Dave

Mark Cavage

unread,
Mar 7, 2014, 8:20:22 PM3/7/14
to res...@googlegroups.com
You need to send an actual JS Error object in the `next` syntax. Like
next(new Error('I did a bad thing'));. To setup correct status codes,
etc, you need to create a subclass of RestError or HttpError.
> --
> You received this message because you are subscribed to the Google Groups
> "restify" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to restify+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Dave Artz

unread,
Mar 7, 2014, 8:26:45 PM3/7/14
to res...@googlegroups.com
Thanks for the quick reply, Mark, makes sense.  What did you mean by 'shorthand this in a route' in the docs?

Mark Cavage

unread,
Mar 7, 2014, 8:29:17 PM3/7/14
to res...@googlegroups.com
Oh just doing:

next(err)

As opposed to:

res.send(err)
next();

Also - I forgot, there is `next.ifError()` support too:

function (req, res, next) {
foo.bar(function (err) {
next.ifError(err);

...
});
}

If that floats your boat. It's like assert.ifError (it does throw, so
there is a perf cost to it). I don't personally use it (I actually
prefer the if block to highlight error handling, and perf cost), but
it is there.

m

Dave Artz

unread,
Mar 7, 2014, 8:42:20 PM3/7/14
to res...@googlegroups.com
Ah, I got it, my confusion was mainly that "err" needs to be an Error object for this to work right.  

In the Bunyan logs, the error was getting logged but was a 200 and hanging...

[2014-03-08T01:37:28.380Z]  INFO: audit/66132 on Airtz2.local: handled: 200 (req_id=35605b80-a662-11e3-b1f5-9f0cfe1064fe, audit=true, remoteAddress=127.0.0.1, remotePort=53240, latency=6, _audit=true, req.version=*)
    GET /error HTTP/1.1
    host: localhost:3001
    connection: keep-alive
    cache-control: max-age=0
    accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36
    accept-encoding: gzip,deflate,sdch
    accept-language: en-US,en;q=0.8
    cookie: session=eyJwYXNzcG9ydCI6e30sImxhbmciOiJlbiJ9; session.sig=a18JIeskQBG549d1kzzJU40iJpM
    --
    err: {
      "error": "I did a bad thing.",
      "statusCode": 500
    }
    --
    req.timers: {
      "bunyan": 456,
      "handler-1": 2706
    }

Out of curiosity, would I be able to tap into that "err" object in a subsequent middleware?  For example, in one of your 'after' events...

Mark Cavage

unread,
Mar 8, 2014, 1:54:28 PM3/8/14
to res...@googlegroups.com
Yeah, it should be there in the after event as the last argument (docs
below). But that doesn't look right -- there's no response in your
audit record; maybe you didn't actually send it?


Event: 'after'

function (request, response, route, error) {}

Emitted after a route has finished all the handlers you registered.
You can use this to write audit logs, etc. The route parameter will be
the Route object that ran. Note that when you are using the default
404/405/BadVersion handlers, this event will still be fired, but route
will be null. If you have registered your own listeners for those,
this event will not be fired unless you invoke the cb argument that is
provided with them.

Dave Artz

unread,
Mar 8, 2014, 3:19:28 PM3/8/14
to res...@googlegroups.com
Twas right in front of me all along.  Thanks much, Mark.  

Restify rocks!
Reply all
Reply to author
Forward
0 new messages