restify / restify/node-restify

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

Open
#1,982 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
10.7k
Forks
975
Avg merge
1d 6h
Merged PRs (30d)
5

Description

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?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the POST /testpost case with restify.plugins.bodyParser({ mapParams: false }) and helperMiddleware, then compare it with the working GET case. Trace the bodyParser-to-middleware request lifecycle and RequestCloseError, and add or update a regression test for delayed next(). Done means asynchronous middleware can call next() after the delay and the POST handler completes without the error.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.