Custom Error not propagated properly on throw statement or next() call Custom Error not propagated properly on throw statement or next() call mongoose mongoose

Custom Error not propagated properly on throw statement or next() call


Setting name attribute of the class in its constructor solves the problem (line no. 3):

class APIError extends Error    constructor: ->        @name = 'APIError'app.use (err, req, res, next) ->    if err instance of APIError        console.log 'Error captured'app.get '/', (req, res, next) ->    #This will work: captured by error handler    throw new APIErrorapp.get '/in-mongoose-callback', (req, res, next) ->    UserModel.where('name', 'Joe').findOne (err, doc) ->        #This one works as expected: captured by error handler        return next new APIError

This is due to one of the changes that landed in CoffeeScript 1.3.3 (MAY 15, 2012):

Due to the new semantics of JavaScript's strict mode, CoffeeScript no longer guarantees that constructor functions have names in all runtimes. See #2052 for discussion.

Note that using throw statement instead of next() inside a Mongoose query callback will not work.


While using express, I extend Error, set the name as prototype property, and perform a stack trace.

class RequestError extends Error    name: 'RequestError'    constructor:(@status, message)->        super message        Error.captureStackTrace @, @constructor

I can do new RequestError 403, 'Invalid username/password.' for a bad user signin, or new RequestError 404, 'Page not found.' for a bad page request. When I catch the error I do

require 'colors'console.error error.stack.red  # logs where any error occuredif error instanceof RequestError    # proper response for user errors    response.status(error.status).send(error.message)else response.status(500).send('Internal Server Error') # for 'other' errors the user only gets back a 500 'Internal Server Error'


It's hard to tell but we had issues on errors until we moved them to the end of the server script, even after the start server. This is using Express with Node, but could give you a hint. Before we had this near the beginning of server file assuming no issues but started working after we moved all our error handling to end. Unsure if router or middleware of framework order of operations issue but seemed to fix our issues.


/////////////////////////////// Start Server/////////////////////////////app.listen(siteConf.port);//////////////////////////// Error Handling//////////////////////////  function NotFoundError(req, message){    this.name = "NotFoundError";    this.status = 404;    this.message = message || (req.method + " " + req.url + " could not be found");    Error.captureStackTrace(this, NotFoundError);}NotFoundError.prototype.__proto__ = Error.prototype;function ProtectedResourceError(req, message){    this.name = "ProtectedResourceError";    this.status = 401;    this.message = message || (req.url + " is protected");}ProtectedResourceError.prototype.__proto__ = Error.prototype;function ValidationError(req, message, errors){    this.name = "ValidationError";    this.status = 400;    this.message = message || ("Error when validating input for " + req.url);    this.errors = errors;}ValidationError.prototype.__proto__ = Error.prototype;function SearchError(req, message){    this.name = "SearchError";    this.status = 400;    this.message = message || ("Error when searching");}SearchError.prototype.__proto__ = Error.prototype;// If no route matches, throw NotFoundErrorapp.use(function(req, res, next) {    console.log("No matching route for " + req.url);    next(new NotFoundError(req));        });// General error handlerapp.use(function(err, req, res, next) {    //console.log("Trapped error : " + err);    // handle exceptions    if (err instanceof ValidationError) {        standardResponse(req, res, {error: err.message, fields: err.errors}, err.status, err.message);    } else if (err instanceof ProtectedResourceError) {        standardResponse(req, res, {error: err.message}, err.status, err.message);    } else if (err instanceof NotFoundError) {        standardResponse(req, res, {error: err.message}, err.status, err.message);    } else if (err instanceof SearchError) {        standardResponse(req, res, {error: err.message}, err.status, err.message);    } else {        standardResponse(req, res, {error: err.message}, 500, err.message);    }});