Home > Enterprise >  Why is timeout request ignored in this Nodejs request
Why is timeout request ignored in this Nodejs request

Time:01-26

Let's assume you have a server in enter image description here

Info about /testkeepalive

  .post('/testkeepalive', async ctx => {
    console.log('request received')
    ctx.request.socket.setTimeout(5 * 60 * 1000)
    ctx.request.socket.setKeepAlive(true)
    await delay(3 * 60 * 1000) // we delay 3 mintues before returning the request
    ctx.body = "nice"
    ctx.status = 202
  })

Client side error: enter image description here

CodePudding user response:

Axios is showing you ERR_NETWORK so I think that means that some intermediary (perhaps a proxy in your hosting environment) has closed the socket.

Below is a test app I wrote that lets me separately set the serverTimeout, the clientTimeout and the serverDelay before sending a response. This allows you to simulate either client or server timeout and see exactly what the axios response is. This is generic Express since I'm not a koa person, but presumably, it is the same http server object in either case.


With these values configured such that the serverDelay is less than both serverTimeout and clientTimeout:

const serverTimeout = 10 * 1000;
const clientTimeout = 8 * 1000;
const serverDelay = 7 * 1000;

Then, I get the appropriate response from the server (no error).


With these values configured such that the serverTimeout is shorter than the serverDelay:

const serverTimeout = 5 * 1000;
const clientTimeout = 8 * 1000;
const serverDelay = 7 * 1000;

Then, I get Error socket hang up ECONNRESET.


With these values configured such that the clientTimeout is shorter than the serverDelay or serverTimeout:

const serverTimeout = 10 * 1000;
const clientTimeout = 5 * 1000;
const serverDelay = 7 * 1000;

Then, I get Error timeout of 5000ms exceeded ECONNABORTED.


So, it all seems to be working for me with no extra infrastructure in between the client and server. So, that plus the ERR_NETWORK error you see from Axios makes me think that a proxy in your hosting infrastructure is responsible for the error.


Here's the code I used:

import express from 'express';
import axios from 'axios';

const serverTimeout = 10 * 1000;
const clientTimeout = 8 * 1000;
const serverDelay = 7 * 1000;

function delay(t) {
    return new Promise(resolve => {
        setTimeout(resolve, t);
    })
}

const app = express();

app.get("/timeout", async (req, res) => {
    await delay(serverDelay);
    res.send("Hello");
});

const server = app.listen(80);
server.timeout = serverTimeout;


try {
    let result = await axios.get("http://localhost/timeout", { timeout: clientTimeout });
    console.log("Got Result", result.data);
} catch (e) {
    console.log("Error", e.message, e.code);
}
server.close();

Note also that there is no need to set a timeout separately on each incoming socket. The server timeout itself will handle that for you.

  • Related