How to send a custom http status message in node / express?

My node.js application is modeled as an express / examples / mvc application.

In the controller action, I want to spit out the HTTP 400 status with a custom http message. By default, the "Bad Request" http status message is:

HTTP/1.1 400 Bad Request 

But I want to send

 HTTP/1.1 400 Current password does not match 

I tried different methods, but none of them set an http status message for my custom message.

My current solution controller function looks like this:

 exports.check = function( req, res) { if( req.param( 'val')!=='testme') { res.writeHead( 400, 'Current password does not match', {'content-type' : 'text/plain'}); res.end( 'Current value does not match'); return; } // ... } 

Everything works fine, but ... it seems this is not the right way to do this.

Is there a better way to set an http status message using express?

+48
express
Jan 04 '13 at 9:24 on
source share
7 answers

You can check this res.send(400, 'Current password does not match') See Express 3.x docs for details

UPDATE for Expressjs 4.x

Use this method (see express 4.x docs ):

 res.status(400).send('Current password does not match'); // or res.status(400); res.send('Current password does not match'); 
+41
Jan 04 '13 at
source

None of the existing answers fulfills what the OP originally requested, which should override the standard Reason-Phrase (text that appears immediately after the status code) Express.

You want res.statusMessage . This is not part of Express, it is a property of the underlying http.Response object in Node.js 0.11 +.

You can use it like this (tested in Express 4.x):

 function(req, res) { res.statusMessage = "Current password does not match"; res.status(400).end(); } 

Then use curl to make sure it works:

 $ curl -i -s http://localhost:3100/ HTTP/1.1 400 Current password does not match X-Powered-By: Express Date: Fri, 08 Apr 2016 19:04:35 GMT Connection: keep-alive Content-Length: 0 
+40
Apr 08 '16 at 19:18
source

One elegant way to handle user errors like this in an expression:

 function errorHandler(err, req, res, next) { var code = err.code; var message = err.message; res.writeHead(code, message, {'content-type' : 'text/plain'}); res.end(message); } 

(you can also use the express built-in express.errorHandler )

Then in your middleware in front of your routes:

 app.use(errorHandler); 

Then, where you want to create the error "Current password does not match":

 function checkPassword(req, res, next) { // check password, fails: var err = new Error('Current password does not match'); err.code = 400; // forward control on to the next registered error handler: return next(err); } 
+10
Jan 05 '13 at
source

Server side (Express middleware):

 if(err) return res.status(500).end('User already exists.'); 

Client side processing

Angular: -

 $http()..... .error(function(data, status) { console.error('Repos error', status, data);//"Repos error" 500 "User already exists." }); 

JQuery: -

 $.ajax({ type: "post", url: url, success: function (data, text) { }, error: function (request, status, error) { alert(request.responseText); } }); 
+5
Mar 29 '16 at 11:23
source

My use case sends a custom JSON error message since I use the express delivery function for my REST API. I think this is a fairly common scenario, so I will focus on this in my answer.

Short version:

Express error handling

Define middleware for error handling, such as other middleware, with the exception of four arguments instead of three, in particular with the signature (err, req, res, next) .... You define the middleware for error handling last after other applications app.use () and routes

 app.use(function(err, req, res, next) { if (err instanceof JSONError) { res.status(err.status).json({ status: err.status, message: err.message }); } else { next(err); } }); 

Raise errors from anywhere in the code by doing:

 var JSONError = require('./JSONError'); var err = new JSONError(404, 'Uh oh! Can't find something'); next(err); 

Long version

Canonical rollover method:

 var err = new Error("Uh oh! Can't find something"); err.status = 404; next(err) 

By default, Express handles this by carefully wrapping it as an HTTP response with code 404 and a body consisting of a message line attached to the stack trace.

This does not work for me when I use Express as a REST server, for example. I want the error to be sent as JSON, and not as HTML. I also definitely do not want my stack trace to be ported to my client.

I can send JSON as a response using req.json() , for example. something like req.json({ status: 404, message: 'Uh oh! Can't find something'}) . If desired, I can set the status code using req.status() . The combination of two:

 req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'}); 

It works like a charm. However, I find it rather cumbersome to print every time I have an error, and the code is no longer self-documenting, like our next(err) . This looks too similar to how a regular (i.e., valid) JSON response is sent. In addition, any errors caused by the canonical approach still lead to HTML output.

This is where the Express middleware appears. As part of my routes, I define:

 app.use(function(err, req, res, next) { console.log('Someone tried to throw an error response'); }); 

I also subclass Error in a custom JSONError class:

 JSONError = function (status, message) { Error.prototype.constructor.call(this, status + ': ' + message); this.status = status; this.message = message; }; JSONError.prototype = Object.create(Error); JSONError.prototype.constructor = JSONError; 

Now that I want to clear the error in the code, I do:

 var err = new JSONError(404, 'Uh oh! Can't find something'); next(err); 

Returning to the middleware for error handling, I change it to:

 app.use(function(err, req, res, next) { if (err instanceof JSONError) { res.status(err.status).json({ status: err.status, message: err.message }); } else { next(err); } } 

A subclass error in JSONError is important because I suspect that Express is checking the instanceof Error first parameter passed to next() to determine if a normal handler or an error handler should be called. I can remove the instanceof JSONError and make minor changes to ensure that unforeseen errors (like a crash) also return a JSON response.

+3
Oct. 15 '15 at 6:57
source

You can use it like this:

 return res.status(400).json({'error':'User already exists.'}); 
+2
May 7, '16 at 19:18
source

If your goal is just to reduce it to a single / simple line, you can set the default values โ€‹โ€‹a little differently ...

 return res.end(res.writeHead(400, 'Current password does not match')); 
+1
May 30 '15 at
source



All Articles