Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Execute Asynchronous Code (Both Promises and Callbacks) in Middleware #1982

Open
vishalkumar14 opened this issue Feb 7, 2025 · 0 comments

Comments

@vishalkumar14
Copy link

vishalkumar14 commented Feb 7, 2025

Bug Report

I thoroughly searched the existing issues in the Restify repository to check if this problem had already been reported. However, I could not find any issue that matches the exact behavior I am experiencing. While there are some discussions around bodyParser, none of them address the specific problem where the request connection is prematurely marked as closed when handling POST requests

Restify Version

v5.0.0 (also tested on latest version as well)

Node.js Version

v22.11.0 ( also tested with 16.19.0)

OS

Ubuntu 20.04 (WSL2), Windows 11

Expected behaviour

Middleware should proceed sequentially to the next handler when next() is called.

Actual behaviour

When using restify.plugins.bodyParser(), the request connection state is unexpectedly marked as closed. If a middleware function performs an async operation (e.g., setTimeout, async/await), calling next() after the delay results in a RequestCloseError.

This issue only occurs for POST requests.

Code

`

const restify = require('restify');


const server = restify.createServer({ handleUncaughtExceptions: true });
server.pre(function (req, res, next) {
    restify.pre.userAgentConnection();

    req.start = Date.now();
    req.requestId = req.header('X-Request-Id') || req.getId();
    return next();
});
server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.authorizationParser());
server.use(restify.plugins.dateParser());
server.use(restify.plugins.queryParser());
server.use(restify.plugins.bodyParser({ mapParams: false }));

server.on('uncaughtException', function (req, res, route, err) {
    res.send(500, { code: 'UNKNOWN', message: 'UNKNOWN' });
});

server.on('after', function (req, res, route, error) {
    console.log("server after event :: ", error)
});

process.on('exit', function () {
    console.log(`Stopped server `);
});

function connectionStateCheck(req, res, next) {
    const connection = req.connection;

    req.on('close', () => {
        console.log(`Connection closed for ${req.url}`);
    });
    req.on('end', () => {
        console.log(`Connection end for ${req.url}`);
    });
    connection.on('close', () => {
        console.log(`Connection closed for ${req.url}`);
    });

    connection.on('end', () => {
        console.log(`Connection ended for ${req.url}`);
    });

    next();
}
server.use(connectionStateCheck);

function helperMiddleware() {
    return function hh(req, res, next) {
        console.log("Middleware started");

        setTimeout(() => {
            console.log("Async operation completed, calling next()");
            req.authdata = {};
            return next();
        }, 3000);
        console.log("Middleware function execution ends");

    }
}

server.get('/', (req, res, next) => {
    console.log("Final handler executed");
    res.send("Hello, world!");
    next();
});

server.use(helperMiddleware());
server.get('/test', (req, res, next) => {
    console.log("test handler executed");
    res.send("test, world!");
    next();
});

server.post('/testpost', (req, res, next) => {
    console.log("testpost handler executed :: ", req.body);
    res.send("test, world!");
    next();
});

server.listen(8080, () => {
    console.log("Server listening on port 8080");
});

`

What's Happening

  • Everything works fine until the request hits bodyParser.
  • bodyParser executes successfully and passes control to the next middleware (helperMiddleware).
  • The next middleware (helperMiddleware) runs synchronously until it reaches setTimeout().
  • Before setTimeout() executes, Restify marks the request connection as closed.
  • Calling next() after the async operation throws RequestCloseError.
  • Removing bodyParser or helperMiddleware fixes the issue but i need both the middleware
  • Only affects POST requests (GET requests work fine)

Image

Can anyone please help me with the issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant