always run a middleware in expressjs - node.js

i want an expressjs middlware to be executed always.
That is even if there is an error in the next() or not.
is it possible?
example
app.get('/',[middle1,middle2],doIt)
the middle2 should always execute even if the middle1 executes next with error.
NOTE: the middle2 should always execute last and takes the values calculated by the previous middlewares. also there are lot of middlewares between middle1 and middle2.

If middle1 is known to not use any async operations from which it calls next(), then you can wrap it and put a try/catch around it so that if it throws, you can just call next() on its behalf.
If it does use async operations or you don't know if it will use async operations, then you will only catch its exceptions if it throws synchronously (before it goes async) and you will not be able to catch any exceptions that it throws asynchronously. About the best you could do for async behavior is to set some sort of timeout in your wrapper. If it hasn't called next() within some period of time (either because it threw an exception or just failed in some other weay), then you call next after the timeout period.
Wrapping a non-async middle1 could look like this:
function wrap(fn) {
return function(req, res, next) {
var nextCalled = false;
try {
fn(req, res, function() {
nextCalled = true;
next();
});
} finally {
if (!nextCalled) {
next();
}
}
}
}
app.get('/',[wrap(middle1),middle2],doIt);
The wrap() function inserts a stub as the middleware function. That stud inserts its own next() function so it can tell if the actual middleware function calls next() or not. It then wraps an exception handler around the middleware function so if it throws an exception synchronously, then it can recover. After the function returns, it checks to see if next() was called and, if not, it calls it.
As explained earlier this approach only works if the middleware function is synchronous.

Assuming you do not care about the order of execution, you can simply have function middle2 execute inside app.use.
app.use(middle2);
app.get('/pathx, middle1, middle3, doIt);
middle2 will always be executed on every request. However, middle2 will execute before any of the other middleware
If you require middle2 to execute last in sequence, then a simple modification using the async module should accomplish what you want
async = require('async');
function middleware(req, res, next){
var functionList = [middle1, middle3];
async.series(functionList, function(err, results){
if(err){
middle2(req, res, next);
next(err);
}
middle2(req, res, next);
next();
}
}
app.get('/pathX', middleware, doIt);

Related

How to test try catch code in javascript using jest and including a next() call with middleware in express?

I am creating an API and I want to know how to test a try catch block. I want to make sure that error catch by the block is passing throw next() in express to the next middleware.
Here an example, this is my callback to POST method:
function create (req, res, next) {
try {
const data = {}
response(req, res, data, 201)
} catch (error) {
next(error)
}
}
I want to test that next is called. I am planing to use sinon to do it, but I want to simulate the error and verify that catching the error.
This is an screen of my coverage in jest.
If it were too much effort to reproduce an actual error, I'd just not cover that statement.
Thanks to Jest's mock functions it's possible to spy on functions, methods and modules and temporarily replace it's implementation and return value.
https://jestjs.io/docs/mock-function-api
That would be something like
// replace the implementation for your stub
const spy = jest.spyOn(response).mockImplementation(() => { throw new Error(); });
...
expect(spy).toHaveBeenCalled();
spy.mockRestore(); // restore the implementation
Mind you this syntax work for functions. If it this a method from a class, then it would be jest.spyOn(YourClass.prototype, 'methodNameInsideQuotes'). Jest is well-documented and you should get it working with no hacks.

Why Array.forEach() is not blocking the middleware?

I know that Array.forEach is synchronous.
But I've this code:
function middleware (req, res, next) {
Array.forEach(
Array.forEach(
if(true) { return next(); }
)
)
return res.send("false");
}
// next()
function isTrue (req, res) {
return res.send("true");
}
And every time I execute it, it sends two headers. First the isTrue function header, and later, the middleware function header.
I understand that if Array.forEach() is synchronous, it should be executed before res.send("false"). But it's not the behaviour. So there is something that I don't understand.
To answer the complete question we'd need to see your code, but to answer the very basic javascript question, the return inside forEach only returns from forEach and not from your outer middleware function. So everything within the middleware function is still executing after forEach.
Again, it's impossible to offer a real solution, but instead of forEach you'd typically use some for these kind of checks.
const ret = [1,2,3].some(e => e === '<yourCondition>');
res.send(ret);

How to skip part of the middlewares that are on the stack in Express js

I am working on a backend of web application. And I have made a bunch of middlewares to be executed for each request that comes in -- [logging(before), authentication, Etag(Before), Nonce, httpRequest, Etag(after), logging(after)]. Now my problem is that, while processing each request, there are some special cases happen when the request should skip the rest of the middleware and just do logging. I can do it the dump way just make all the middleware to check if certain condition has happened and if true just call next(), and otherwise process the request using the middleware. But I am wondering if there is a clever way to do this?
Here is the snippet of the code I am currently using to configure the order of the middleware to be executed:
async.series(operations, function(err) {
if(err) {
console.log('Something blew up!!!!!!');
return next(err);
}
console.log('middleware get executed');
// no errors so pass control back to express
next();
});
Where the "operations" variable is the list of middlewares I need to execute in order. I need to use the async.series() since I need to make the order the middleware configurable. Is there a clever I can keep the order of middlewares configurable and fulfill my request as I said above?
EDIT:
An example where I need to skip the rest of the middleware is when authentication fails and write the statusCode to be "401 unauthorized", then for the stack of the middleware [logging(before), authentication, Etag(Before), Nonce, httpRequest, Etag(after), logging(after)], I will jump from authentication to logging(after). and then that would be the end of the request.
I had tried to understand your's concern
I am giving a snippet to execute middle ware function in row on the basis of need.
async.each(operations, function(operation, callback) {
if(operation) {
// if operation is required execute here
callback();
} else {
// otherwise skip just to call callback() here
callback();
}
}, function(err){
if( err ) {
console.log(err);
} else {
next();
}
});
all the operations in an array and to execute all one by one async provides .each.
Its not mandatory to call each operation. You just skip by call callback() in else condition. I want to say that in if clause you can put your mandatory execution condition.
Thanks

Node-soap client and scope of the callback

I'm using the node-soap client from milewise (create API by the way), but I have some difficulties to get the results of the callback to the right scope.
Here is the code I have for now:
function generateSoapRequest(req, res, next)
{
soap.createClient('http://127.0.0.1:' + cfg.service_port + cfg.service_url_path,
function(err, client) {
client.CXIf.CXIf.CXProcessXML(
{"XMLRequestData": {"CXLogon": {"UserID":"1901007", "Password":"2580", "LogonType":11 } } },
function(err, result, body) {
if (err) {
console.log(err);
return;
}
console.log(result);
var cxresponse = result.XMLResponse[0].CXResponse;
console.log('SessionID:' + cxresponse.SessionID + ' SessionInstanceID:' + cxresponse.SessionInstanceID);
});
});
}
function getVoiceMailInformation(req, res, next) {
var cxresponse = generateSoapRequest(req, res, next);
var something = doSomethingNext(cxresponse);
}
function doSomethingNext(cxresponse){....; return something;}
Basically, when I launch the getVoiceMailInformation(), it creates a soap client and request some information through the generateSoapRequest().
The next step would be to get the result of that function (not implemented in the code above, because I don't know how) and do something else.
My problem is soap.createClient is asynchronous, so the callback is fired well after the function is complete.
What would be the best approach ?
(Maybe it's something trivial, but the scope of an anonymous function in javascript is something that is killing me.)
Any help will be very appreciated.
Basically you can't do something like:
var cxresponse = generateSoapRequest(req, res, next);
because the function you're calling invokes asynchronous code, and therefore can't return a value that's determined by that code. The normal way around this is to give the function an extra callback parameter for a function that will be called with the result once the result becomes available. It doesn't have to be an anonymous function; it can be a named function. In your case, (assuming you've modified generateSoapRequest to take a callback as its fourth argument and call it when the results are ready, you could write
generateSoapRequest(req, res, next, doSomethingNext);
and then doSomethingNext will be called with cxresponse as an argument. Of course, since doSomethingNext also gets called asynchronously, it can't return a value either, so you'll have to apply the same technique to it.
The async module can make this sort of thing easier: in particular, its "waterfall" pattern is useful when you have a bunch of functions that have to run in sequence, each being called back from the previous one.

How does Express/Connect middleware work?

I am learning Node.js, and I have read some tutorials, like The Node Beginner Book for learning the core funcionality. But the more I read some examples, the more doubts I start collecting.
On the further example, obtained from a tutorial, we can see that for a CRUD 'read' request for key /documents/titles.json, we are returning a value:
app.get('/documents/titles.json', loadUser, function(req, res) {
Document.find({ user_id: req.currentUser.id },[], { sort: ['title', 'descending'] },
function(err, documents) {
res.send(documents.map(function(d) {
return { title: d.title, id: d._id };
}));
});
});
On this example, the function loaduser() is used for authentication purposes:
function loadUser(req, res, next) {
if (req.session.user_id) {
User.findById(req.session.user_id, function(err, user) {
if (user) {
req.currentUser = user;
next();
} else {
res.redirect('/sessions/new');
}
});
}
}
What I don't understand is:
I suppose that node.js, before start executing the app.get, it goes to loaduser function. loadUser() function has three parameters: req,res,next, but I don't see, at least, how you pass from app.get() the "req" parameter to loadUser(). From where does it come?
Inside loadUser() function, when you execute next(), it means that the function app.get()" can continue its procedure, but this req.currentUser = user, is the same req that is used on app.get() function?
Inside loadUser() function, when you execute res.redirect() code, automatically breaks the procedure on app.get() function, right? it looks like it doesn't return to Document.find().
The questions you've asked are about the Express framework internals specifically:
When you call app.get(route, loadUser, final) Express will make a stack (array) with the loadUser and final function functions and it will know that when you call next it should execute the following function in the stack with the same req and res params.
When you call next it will just pass to the next function in the middleware stack.
Since you call res.redirect and you don't call return, it won't pass to the next function in the stack (the one with Document.find).
Resources:
http://howtonode.org/getting-started-with-express
I think in order to be comfortable with this you need get familiar with idea of middleware and how it's used in connect framework.
I've found few articles where this subject explained well enough. Take a look there:
http://howtonode.org/connect-it
and here http://stephensugden.com/middleware_guide/
the main idea is you have a set of layers and each time when new request arrives it goes through each level and on each level you can decide what to do with that. You can stop at some level, do something and return response or you can pass it to the next layer

Resources