Home > Software engineering >  Rerun a request after fixing some problem with express.js
Rerun a request after fixing some problem with express.js

Time:12-25

My express.js application interfaces with an internal application that once in a while changes its exposed connection port.

If a request fails, next() will call an error middleware function that checks the internal application's port and updates it if needed.

At this point I would like to automatically reprocess the request from the initial route, i.e. restarting the middleware stack from the beginning.

How can I do that? I only know how to go down the middleware stack but not how to go back up.

I could send a 503 http code to the browser to have it retry the request but it feels silly not to reprocess it directly on the server.

EDIT

Attaching some code to make it clearer:

function getInternalPort() {
    ... read from file current port of internal application server...
}

let port = getInternalPort()

app.get('...a route...', async (req, res) => {
    try {
        const result = await functionThatUsesPort()
        res.json(result)
    } catch (error) {
        next(error)
    }
}

const errorHandler = (error, request, response, next) => {
    if (error.code == 'ECONNREFUSED') {
        port = getInternalPort()

        ??? CODE TO REPROCESS THE REQUEST ???

    } else {
          res.json(null);
          console.log(err);
    }
}

app.use(errorHandler)

CodePudding user response:

I am not aware of any Express features that allows you to restart routing over again.

You can, however just create your own wrapper function that will do one retry after resetting the port and use that in whichever request handlers you want retry with. This way, you can just handle the retry yourself and not be asking Express to do it for you:

function getInternalPort() {
    ... read from file current port of internal application server...
}

async function retryUponPortError(fn, next, ...args) {
    try {
        const result = await fn(...args);
        return result;
    } catch (error) {
        if (error.code === 'ECONNREFUSED') {
            port = getInternalPort()
            try {
                const result = await fn(...args);
                return result;
            } catch(error) {
                next(error);
            }
        } else {
            next(error);
        }
    }
}

let port = getInternalPort()

app.get('/someroute', async (req, res, next) => {
    const result = await retryUponPortError(functionThatUsesPort, next, arg1, arg2);
    res.json(result);
}

const errorHandler = (error, request, response, next) => {
    res.json(null);
    console.log(err);
}

app.use(errorHandler)

Note, this code also saves you from having to do the try/catch in your own request handler as that is done in the retryUponPortError() wrapper.

Note, arg1 and arg2 are whatever arguments you might want to pass to your functionThatUsesPort() call. You can have zero arguments or as many as you want. Whichever ones you pass after the next argument to retryUponPortError() will be passed to your function.

CodePudding user response:

You can re-route the request using next('route'). So, in the errorHandler function, just put next('..a route') and it will restart the chain.

  • Related