-1

I have a function similar to the code below - it makes a fetch, does things when the call is successful or not, and returns a promise to be handled downstream:

const myFunc = (): Response => {
  return fetch('http://something')
    .then(r => {
      console.log('the call went through, the return code does not matter')
      return r
    })
    .catch(err => {
        console.error(`ah crap, the call failed completely: ${err}`)
        // and here I do not know how to return a new Response
      }
    }
}

myFunc().then(r => {
  console.log('do something once myFunc is over')
})

My intention is to run some code once myFunc is done, but I need to account for the case the call completely fails (no DNS resolution, rejected call, ...). For that I need to create and return in the catch() a Response promise with, for instance, a forced 503 return code (which is not really correct because the server did not even answer, but anyway).

My question: how can I create such a Response promise?

WoJ
  • 27,165
  • 48
  • 180
  • 345
  • 1
    It's actually much simpler if you use `async` `await` and a common or garden `try{}catch{}` if you can – Liam Nov 11 '21 at 13:59
  • 1
    Why do you need to make a network failure look like an HTTP failure? Why not just let it look like what it is, a network failure? – T.J. Crowder Nov 11 '21 at 14:01
  • @T.J.Crowder: because I want to do something once the fetch is done (whether the call is successful or not will not matter for that "something", it just needs to be after the fetch (successful or not)). – WoJ Nov 11 '21 at 14:04
  • you can `return Promise.reject(someObject);` in the catch so that callers see the promise fail. `someObject` can be whatever you want the caller to see as the rejection value (including `err` if it makes sense). Then your caller can handle the promise rejection appropriately – Always Learning Nov 11 '21 at 14:05
  • @WoJ - You don't have to create a fake HTTP error to do that. – T.J. Crowder Nov 11 '21 at 14:07

1 Answers1

2

I would encourage you not to turn a network failure into an apparent HTTP failure (503), but since you've specifically asked how to do that, you can do that by building your own Response object:

const myFunc = (): Response => {
    return fetch("http://something")
    .catch(err => {
        console.error(`the call failed completely: ${err}`)
        return new Response(null, {
            status: 503,
            statusText: "Fake 503",
        }); 
    });
};

or if you want to use an async function:

const myFunc = async (): Response => {
    try {
        return await fetch("http://something");
    } catch (err) {
        console.error(`the call failed completely: ${err}`)
        return new Response(null, {
            status: 503,
            statusText: "Fake 503",
        }); 
    }
};

(Note that there's no need for your .then in the first one (unless you want to do the console.log).)

But, I would strongly encourage you not to do that. Instead, handle this at the point of the call, via a .finally handler (or a try/finally block in an async function).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thank you for the advice - especially about the `finally` that indeed solves my problem cleanly. I am glad anyway about the information about creating the promise, this is good to know. Thanks! – WoJ Nov 11 '21 at 19:09