Skip to content

Hi, My Name is Ben

  • About

Error Handling with Node.js and Express

November 4, 2017 by Benjamen

Probably a topic that has been written on quite a bit but as with some blog posts, doing it one more time is hopefully another piece of community documentation as well as potentially helpful to someone struggling with a task.

Express is probably the web framework that most people hear/learn about first and with my limited Node experience the first one I came across.  The following paragraphs won’t be about competitors to it or really more beyond what the title describes, but if you are interested, check out (there are several others)

  • Hapi (https://hapijs.com/)
  • Socket.io (https://socket.io/)

This week while looking at a bug in our platform, I realized quickly that the application was not the problem, yet the underlying API which is written in Node and utilizing Express.  I kept seeing in the logs “Can’t set headers after they are sent to the client”.  When looking at the route, the first thing I noticed was that when an error was occurring the code was just using 500 as a catch all and then calling

1
2
3
4
if (error) {
    next(new Error("some message"));
}
res.status(200).json({"some result"});

Beyond the generic exception, in the app.js there was an attempt at an error handler setup which was also sending headers back to the requestor.  So to clean this code up and put a better status on response I changed to this

1
2
3
4
5
6
7
8
9
 
if (error) {    
    let error = new Error("some message");
    error.status = 404; // add status to the object for later use
    return next(new Error("some message")); // bail out now and don't wait
}
 
res.status(200).json({"some result"});
 

So I cleaned up the code inside of the route which both returns a response correctly and doesn’t double send headers as that res.status(200).json({}) won’t be called unless there truly are no errors in the processing that the API is doing. Now popping on over to app.js which handles app setup and route configuration, I added the following at the bottom of the file.  Important Note: Adding a wildcard route must be at the bottom as it is essentially a “fallout” and it’ll match anything.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
app.get('*', function(req, res, next) {
    var err = new Error();
    err.status = 404;
    next(err);
});
 
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500).json( {
            message: err.message,
            error: err
        });
    });
}
  
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500).json( {
        message: err.message,
        error: {}
    });
});
 

Few things about the above.

  1. Note that before anything I have that wildcard route and I’m treating those requests as Not Found and returning 404 as the HTTP status.
  2. Development based route for error handling.  In the payload in the response, I’m setting error: err which will show the actual descriptive error that I probably care about only when in development. Notice no next() as I want to end the pipeline right there
  3. The production handler that only returns the HTTP status and the error message I want.  Such as “Invalid Request”, “Bad Request, check your parameters” or whatever I want to return to the caller.

Like I mentioned in my last post, I’ll be sharing things I’ve learned, am learning or just general fodder along the way.  I hope this is helpful to someone and if not applicable to what you are working on, perhaps just something new that you can file away!

facebooktwittergoogle_plusredditpinterestlinkedinmail

Post navigation

Previous Post:

My First Month with Node.js

Next Post:

Validating User/Computer Supplied Input

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Spring Boot, Logback and Logstash
  • Covariant Method Return Types in Java
  • From C# to Java
  • Time series data in MongoDB
  • Documenting your ASP.NET Core Web API with Swashbuckle

Recent Comments

  • Benjamen on From C# to Java
  • Mike Graf on From C# to Java
  • DJ on Takeaways from my First Analytics Conference

Archives

  • March 2019
  • December 2018
  • September 2018
  • August 2018
  • December 2017
  • November 2017
  • October 2017
  • March 2016
  • February 2016
  • November 2015

Categories

  • Agile
  • AWS
  • Data
  • Java
  • Life
  • Programming
  • Tech
  • Uncategorized

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
© 2021 Hi, My Name is Ben | WordPress Theme by SuperbThemes