spacenick
spacenick

Reputation: 1185

Express/Node.JS middleware raising error, keeps processing

I'm beginning under NodeJS/Express and I'm facing the following problem (I probably didn't get all the tricks of async programming yet)

I've made a middleware in charge of checking if a oauth_token paramters is passed (actually implementing oAuth layer on my node server)

I'm doing this :

function myMiddle(req,res,next) {
  var oAuthToken = req.query["oauth_token"];
  if (oAuthToken == undefined) {
            res.send(406);
            res.end();
    next(new Error('No token provided'));   
}
/* Basically doing some DB stuff with MongoDB, connecting and using oAuthToken provided to query, etc.. */

The thing is that I expected the code to "die" when he doesn't receive the oauth_token parameters in the query string. It's actually raising me an error and returning greatly 406 error to my HTTP client, but code keeps processing behind and raises me mutable headers errors caused by my processing code after, and my script dies.

Something I'm missing? Thanks by advance.

Upvotes: 1

Views: 3115

Answers (3)

hkyo89
hkyo89

Reputation: 61

This might be late, but I just encountered this issue as well. You can actually pass the error to ErrorHandler so that the middleware would not continue to the next middleware or router while you can send the HTTP status code you want.

Your middleware

function myMiddle(req, res, next) {
  // Do validate your OAuth token
  // you might want to do better validation of the token here
  // instead of just checking its existence
  //
  // var oAuthToken = req.query['oauth_token'];
  //
  // According to JSLint, you can just directly select the object as:
  //
  // req.query.oauth_token

  if (req.query.oauth_token === undefined) {

    // Just let the ErrorHandler does the rest
    // like redirecting or just send message to client
    var err = new Error('Unauthorized access.');
    err.status(406); // Or 403, or any HTTP status code

    // Pass it to ErrorHandler
    next(err);

  } else {
    // Do something here, or just
    next();
  }
}

Your ErrorHandler

app.use(function(err, req, res, next){
  if (err.status == 406) {
    // You can just do res.sendStatus()
    res.sendStatus(406); // Set HTTP status code as 406 and send message to client

    // Or chaining res.status() with res.send()
    res.status(406).res.send(); // or res.render(), or res.json()

    return;

  }

  // Others
});

More about ErrorHandler: http://expressjs.com/ja/guide/error-handling.html

Upvotes: 1

freakish
freakish

Reputation: 56467

If your oAuthToken is undefined Node.js makes a response. After that you fire next(...) which tries to make another response to the same request. This fails and you see what you see. Note that in Node.js using res.send(); and res.end(); does not stop your function. So what you need is to do the following:

function myMiddle(req,res,next) {
  var oAuthToken = req.query["oauth_token"];
  if (oAuthToken == undefined) {
    next(new Error('No token provided')); // handle everything here

    // res.send(406);
    // res.end();
    // unnecessary, throws errors because you try to respond twice
  }
  // do something if this is fine
}

or do it the other way - use res.send(406); res.end(); without next(...).

Upvotes: 2

stefanw
stefanw

Reputation: 10570

Do you have express error handling (app.use(express.errorHandler()) in your middleware stack?

Also see the Express middleware section for details on how to use next().

Upvotes: 0

Related Questions