How to call middleware next() in async function?

1,795 views
Skip to first unread message

Aga

unread,
Sep 17, 2012, 3:13:35 PM9/17/12
to nod...@googlegroups.com
Hi,

I'm a Node.js newbie and have a middleware related question. Here is the code:


// router starts controller()
...
exports.controller = function controller(req, res, next) {
  model.getFileData("/tmp/foo.txt", function foo(err, data) {
    if(err) {
      console.log("error while reading file");
      return(next(new Error());  // exits foo() and NOT controller()
    }
    console.log("success");
    // do something with data
  });
  return(next());
}



If the model returns an error, I want to call controllers next() to jump to the next middleware function.
I'm not sure how to organize the code, could you give me some examples?

Thank you
Aga

Martín Ciparelli

unread,
Sep 17, 2012, 3:24:11 PM9/17/12
to nod...@googlegroups.com
First of all try to organize your code a little better, that will help you. Try not to have more than 3 levels of indentation whenever possible.
I assume you are using expressjs? If so, then you just need to call next() to call the next middleware. If you do with new Error() as the only arg, then I think it will call the next function(err, req, res, next) in the stack, but you can check con expressjs.com if you want to be 100% sure about this.

2012/9/17 Aga <aga...@gmail.com>

Aga

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

José F. Romaniello

unread,
Sep 17, 2012, 3:31:01 PM9/17/12
to nod...@googlegroups.com

The problem I see is that you car calling next() before you finish reading the file.

But, I dont understand why you want to let know to the next middleware that this one has fail?

I havent seen that a lot.. For instance lot of authentication code do something along these lines:

function addUserToRequest(req, res, next) {
  getUser(req.session.userId, function foo(err, user) {
    if(err) {
       return res.send(401); ///respond with unauthorized  and do not call the next middleware.
    }
    req.user = user; //put the user in the request object so the next middleware can use it
    next(); //call the next middleware.
  });
}

2012/9/17 Aga <aga...@gmail.com>

Aga

unread,
Sep 17, 2012, 5:12:18 PM9/17/12
to nod...@googlegroups.com
Thanks for your quick answers. I think I have to split my question in two parts:

1.)
If an error occured, the controller can send the response to the client. But, as Martin wrote, the middleware is able to catch an err via function(err, req, res, next). We wouldn't need this feature, if the controller would send always the response. I think the "catch-error" middleware function is useful to log error details etc.

e.g.:

server.get(/foo,
  [
    controller.foo,
    controller.bar,
    controller.catchError
  ]
);

No errors: router -> controller.foo -> controller.bar -> response to client
Error in foo(): router -> controller.foo -> controller.catchError (gets error object from foo's next(err)) -> log details and send response

Please correct me if I am wrong!


2.)
If (1) is correct and I should use a middleware "catch-error" function:
Can you please give me an (error and success) example how to use next(), if the controller runs a callback function?

e.g.:

// controller function
exports.foo = function controllerFoo(req, res, next) {
  model.getFileData("/tmp/foo.txt", function readMyFile(err, data) {

    if(err) {
      console.log("error while reading file");
      return(next(new Error());  // doesn't work because return exits readMyFile() and NOT controllerFoo()

    }
    console.log("success");
    // do something with data
  });
  return(next());    // doesn't work because next() will be called before reading the file
}


Thanks a lot for your help.

tjholowaychuk

unread,
Sep 18, 2012, 12:11:06 AM9/18/12
to nodejs
we were actually just talking about this today, for logic tasks that
are
outside of the req/res cycle since you've already responded etc we
might
treat subsequent next(err) calls as app.emit('error', err) for
delegation. These
would still not be handled by the same error handling middleware,
because you
can no longer respond
> > 2012/9/17 Aga <aga...@gmail.com <javascript:>>
>
> >> exports.controller = function controller(req, res, next) {
> >>   model.getFileData("/tmp/foo.txt", function foo(err, data) {
> >>     if(err) {
> >>       console.log("error while reading file");
> >>       return(next(new Error());  *// exits foo() and NOT controller()*
Reply all
Reply to author
Forward
0 new messages