0

I have this POST method which uses FetchURL middleware to fetch data from the url submitted by the user.

router.post('/', FetchURL, (req, res) => {

    console.info('data received');
    ...
})

Everything works with response.ok being true, but the contrary case doesn't quite work as expected. I don't want next to be called when response.ok equals false.

But I get to see "data received" logged to the console which means the next function does get called on its own.

fetch_url.js

function FetchURL(req, res, next) {
    fetch(req.body.input_url)
        .then(response => {
            if(response.ok) 
                return response.json();

            // else render error message on the client machine
            res.status(response.status)
                .render('index', {
                    errStatus: [response.status, response.statusText]
                });

            /* Throwing an Error here is the only way I could prevent the next callback */
            // throw new Error(`Request failed with status code ${response.status}.`);
        })
        .then(data => {
            req.data = data;
            next();
        })
        .catch(err => console.error(err));
}

I could not find anything relevant on the documentation of expressjs middleware. The only way I could prevent next from being called is by throwing an Error on the server.

What happens behind the scene here?

Sapinder Singh
  • 559
  • 6
  • 21

1 Answers1

1

try making a second check before next is called like following

function FetchURL(req, res, next) {
    fetch(req.body.input_url)
        .then(response => {
            if(response.ok) // wrap your response in a temporary object.
                return { fail: false, data: response.json() } ;

            // else render error message on the client machine
            res.status(response.status)
                .render('index', {
                    errStatus: [response.status, response.statusText]
                });

            /* Instead of throwing an Error, return something indicating error */
            return { fail: true };
        })
        .then(data => {
            // check if previous procedure has failed.
            if(!data.fail) {
                req.data = data.data;
                next();
            }
        })
        .catch(err => console.error(err));
}
artX
  • 121
  • 4
  • but the question remains the same, *"What causes the execution of `next`?"* – Sapinder Singh Feb 13 '21 at 14:51
  • 1
    [then method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then) is chained up from fetch. if previous async promise is succesfully resolved, following thgen is called with resolve/ returned value. since you close your callback function after error rendering, 'undefined' will be resolved automatically andget passed to consequent then method. – artX Feb 13 '21 at 14:57
  • Oh, so is it possible to cancel resolving the next promise? Or exit the chain? – Sapinder Singh Feb 13 '21 at 15:03