Skip to content

Instantly share code, notes, and snippets.

@Rob-ot
Last active December 14, 2015 00:29
Show Gist options
  • Save Rob-ot/4999734 to your computer and use it in GitHub Desktop.
Save Rob-ot/4999734 to your computer and use it in GitHub Desktop.
An idea for standard errors in Node.js

The idea is that we could have standard error types that are not tied to anything.

These errors can be used thought the app including external libraries.

Specific errors types can be handled easily to achieve different behavior.

HTTP middleware would be included to easily translate error types into relevent HTTP status codes.

Some error type ideas: InvalidParameter(s) = HTTP 400 Unauthorized = HTTP 401 Could not connect to backend = HTTP 500 Timeout = HTTP 504

I wouldn't want too many types to avoid overlapping.

You could also include custom middleware to just pass the error down in json format and let your client application maintain and use the same error types.

CommonErrors will also be Errors for backwards compatibility.

var cerr = require("commonError")
var express = require("express")
var users = require("./users")
var app = express.createServer()
app.use(cerr.middleware())
app.use(function (req, res, next) {
checkLoginCookie(req, function (err, isValid) {
if (!isValid) return res.send(new cerr.Unauthorized())
next()
})
})
app.get("/user/:userName", function (req, res) {
users.getUser(req.userName, function (err, user) {
res.send(err || user)
})
})
var http = require("http")
var cerr = require("commonError")
module.exports = {
get: function (url, cb) {
var request
var timeout = setTimeout(function () {
request.kill()
cb(new cerr.Timeout("Timeout when doing GET of " + url)) // will end up sending a 504
}, 10000)
request = http.get(url, function (err, data) {
clearTimeout(timeout)
if (err) return cb(err) // will end up sending a 500
cb(null, data)
})
}
}
var cerr = require("commonError")
var request = require("./request")
module.exports = {
getUser: function (userName, cb) {
if (!userName return cb(new Cerr.InvalidParam()) // will end up sending a 400
request.get("http://users.com/user/" + userName, function (err, user) {
if (cerr.is(err, cerr.Timeout)) { // specifically handle a timeout error
return request.get("http://otherusers.com/user/" + userName, cb
}
cb(err, user)
})
}
}
@addisonj
Copy link

Express has error middleware like this:

app.get("user/:userName", function(req, res, next) {
  users.getUser(req.params.userName, function(err, user) {
    if (err) return next(err)
    if (!user) return next(new NotFound("could not find user"))

    res.json(user)
  })
})
// express 3.0
app.use(function(err, res, res, next) {
 // see below, same from here on
})
// express 2.0
app.error(function(err, req, res, next) {
  // express works such that if you next() and error, it gets forwarded here, you can have multiple of these...
  // log it depending on type
  if (err.type == "critical") {
    sendEmail("oh noes!", err)
  }

  next(err)
})
app.error(function(err, req, res, next) {
  res.json(formatError(err))
})

I prefer this as it fits well in express and you don't have to overwrite anything to get new behavior. Just add another error middleware and you can do whatever you want.

Also, I have this repo:

https://github.com/addisonj/stdError

we could make it part of that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment