9

Backstory: I'm trying to debug an issue in one piece of middleware that I think is coming from other piece. But, I'm not sure. So anyway, I would like to be able to check what middleware is actually being called, because I'm not sure of the ordering.

Is it possible to inspect the set of middleware that is currently being used?

I have tried to find any piece of internal state where Express might be storing the middleware, but I was not able to.

hrdwdmrbl
  • 4,814
  • 2
  • 32
  • 41
  • Can you elaborate on the issue, provide some code for us to check out – Kop4lyf May 22 '15 at 19:39
  • Very generic stuff, like: ``` var app = require('express'); app.use(compression()); app.use(passport.initialize()); app.use(bodyParser()); app.use(cookieParser()); ``` etc – hrdwdmrbl May 22 '15 at 20:35
  • I think your issue might be due to order of middleware, means bodyParser/cookieParser are usually the first, we call as we need to modify the request as soon as it comes. I have put an elaborate answer also so that you can find out if it works for you. That is how I debugged my middleware issues :) – Kop4lyf May 23 '15 at 04:25

2 Answers2

6

You can't see what is specifically "middleware", but you can inspect all registered handlers.

In express 4:

// Routes registered on app object
app._router.stack

// Routes registered on a router object
router.stack

Fine for inspection/debugging, probably not a great idea to program against any variable prefaced with an underscore.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Adam Terlson
  • 12,610
  • 4
  • 42
  • 63
6

How middleware works:

The middlewares are generally used to transform a request or response object, before it reaches to other middlewares.

If you are concerned with the order in which the middlewares are called, express calls the middleware, in the order in which they are defined.

Example,

app.use(compression());
app.use(passport.initialize());
app.use(bodyParser());
app.use(cookieParser());

the order is

  1. compression,
  2. passport,
  3. bodyParser,
  4. cookieParser

(plus I think your bodyParser and cookieParser middlewares should be before the other middlewares like passport).

That is the reason why the error handling middlewares are kept at last, so that if it reaches them, they give an error response.

So basically, request drips down the middlewares until one of them says that it does not want it to go any further(get, post methods are such middlewares, that stop the request).

Now, the debugging part:

You may not be able to inspect the middleware properly internally, but you can check whether middleware has worked properly by inserting your own custom middleware in between and then put a breakpoint on it.

Let's say you want is to debug what happened to your request after the bodyParser middlewares does it tasks, you can do is put your custom middleware in between and check the request and response whether they are modified properly or not. how you do this is by following example.

Example,

app.use(bodyParser());

//custom middleware to inspect which middleware is not  working properly
app.use(function(req,res,next){
   console.log("check something!"); //do something here/put a breakpoint
   next(); 
   /*this function is the third parameter 
   and need to be called by the middleware 
   to proceed the request to the  next middleware,
   if your don't write this line, your reqest will just stop here.
   app.get/app.post like methods does not call next*/
});

app.use(cookieParser());

This is one way in which you move this custom debugger in between the middlewares, until you figure out which one is giving faulty outputs.

Also, if you want to check the middlewares functionality, you can look at the documentation of those middlewares. They are quite good.

Check by playing with your custom middleware.

Kop4lyf
  • 4,520
  • 1
  • 25
  • 31
  • Thanks for the thorough response. One of the problems for me is that we have ended up with a lot of middleware, some of it is added conditionally, and not all of it is added in the same place. The app object is passed around all over the place so stepping through is difficult. I can't get a good idea of what is even being run because the code is so disorganized! I should have maybe mentioned this in my question, but the ideal solution to my problem is something similar to what the command `rake middleware` does for Ruby on Rails http://tinyurl.com/pyjt6vv – hrdwdmrbl May 25 '15 at 14:55