Next(): difference in behavior in subroutines

Hi all, somewhat of a noob with Express, running into something that works on Windows but doesn’t work with Linux.

I’m using a middleware (req, res, next) and I’m passing next into a subroutine, like this:

app.use (req, res, next)
{
// … some code

subroutine(req, res, next);

return;
}

subroutine = async function(req, res, next)
{
// some more code

next();

}

The idea is, I don’t want to execute next() till the subroutine is finished.

This works great on Windows, I’m using the Docker desktop and the code works perfectly with no complaints.

On Linux in the cloud, this doesn’t work, it results in a “next is not a function” error.

Firstly, am I doing this the right way? What other method(s) could I use to do this?

And second, who’s doing the type checking here? I’m not using TypeScript, don’t know where this type checking is coming from. ls there a way I can tell Node/Express that “this is a function, don’t complain” ? Is there a way to override the type checking?

Thanks for your help and input!

Not really the type of error you can ignore. If it is telling you that it isn’t a function, you can’t execute it as a function.

I don’t really understand the syntax you have or how it works (no matter the system). app.use takes a path and one or more callbacks.

Do you have a repo with your code?


Can’t you just await the async function inside the middleware function and call next after the await?

const express = require("express");
const app = express();

const logFetch = async (req, res, next) => {
  const json = await fetcher();
  console.log("Fetch res: ", json);
  next();
};

const fetcher = async () => {
  const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
  return await res.json();
};

app.use(logFetch);

app.get("/", (req, res) => {
  console.log('root path')
  res.send("Hello World!");
});

app.listen(3000);

Hi lasjorg, thank you for your message.

I tried your method, it results in another strange error -

Inside my subroutine, I try to set the value of res.locals.var_name, and suddenly I’m getting assignment errors, like it can’t seem to understand what res.locals is

Even though the assignment works just fine in my old code

Your method seems to work, if I move the assignment into the upper layer.

Wierd? Why would it work in the upper layer and not in the lower?

I’m doing something very simple, like res.locals.session_ready = 1

For some reason if I place this assignment where your fetcher() is, it doesn’t work, but it I place it in the logFetch() routine, it works.

(I am of course passing the the res in to the fetcher routine, so in logFetch I call it with const json = await fetcher(req, res, next) and the fetcher declaration is const fetcher = async (req, res, next) => etc )

It’s like the system loses track of the structure of res once it’s passed down. Is this normal? Why is this happening?

Okay, verified - your method works fine in both Windows and Linux, with the one caveat about res.locals.

This is a wierd set of errors from my perspective, maybe I’m missing something basic?

I’m not using typescript or anything, so why is it the system can’t figure out what next is when it’s passed into a subroutine? In a way it’s the same symptom with res.locals, the system seems to be losing track of the type and/or structure of my variables somehow.

The code works, I’d like to understand “why” it works. (Or doesnt work, when the variables are moved down into the lowest subroutine)