0

I'm trying to get async await to work without try/catch

  return await fetch(url, options)
    .then(res => res.json())
    .catch(err => {
      throw new Error(err)
    })

Here is how I make the call:

    const response = await makeApiRequest('/reset', {
        password: password1,
        code
    }, {
        noauth: true
    }).catch(err => {
        debugger;
        msg = err.message;
    });

    if (response) {
        navigateTo('/');
    }

The problem is none of the catch blocks are working. The code is expired and serving a 401.

6
  • why are you using async/await without try/catch? error handling with async/await implies using try/catch Commented Oct 24, 2019 at 3:24
  • 2
    by the way ... a 401 response won't trigger an error/rejection in fetch Commented Oct 24, 2019 at 3:24
  • also, return await fetch should just be return fetch - in an async function you don't need to return await a promise Commented Oct 24, 2019 at 3:25
  • you could probably do something like .then(res => res.ok ? res.json() : Promise.reject(res.statusText)) ... res.ok is only true for response.status = 200->299 Commented Oct 24, 2019 at 3:28
  • I read this article on medium about using async/await w/o try/catch. itnext.io/… Commented Oct 24, 2019 at 3:47

2 Answers 2

2

This is what I got to work:

  return fetch(url, options)
    .then(async res => {
      if (!res.ok) {
        const err = await res.json()
        throw err.message || res.statusText
      }

      return res.json()
    })
    .catch(err => {
      throw new Error(err)
    })

You can call it like this:

        const response = await myFetch('/forgot', {
            email
        }, {
            headers: {
                'x-contact': '[email protected]'
            }
        }).catch(err => {
            msg = err.message;
            return;
        });

        if (response) {
            push('/');
        }
Sign up to request clarification or add additional context in comments.

Comments

0

Fetch API fails only if it can't make a request. And if it can, fetch will be executed successfully even if it has a bad status.

Because throw new Error(err) never been called, it just be call when you try to parse a invalid string content to a json object (res.json()). I guest, in 401 case your server return a valid json string like {message: "Unauthorized"}, then res.json() working fine, and does not have any error has been throw.

If you want to catch http error, then http status code of res object is a right way:

  return await fetch(url, options)
    .then(res => {
      if (res.status >= 300) { // error http status code range
        throw new Error(res.status) // throw a error to the catch block
      }
      return res.json();
    })
    .catch(err => {
      throw new Error(err) // catch and throw to the error of previous `.then` block
    })

Then try again.

3 Comments

How should I serve a 401? This doesn't work either. I can get res.status but I want the text too.
@chovy How should I serve a 401? what do you mean how? you respond with 401 status ... but I want the text too huh? do you mean res.statusText?
just for res.json() 's error. Not for http error that's where you are wrong - that catch will catch the error thrown in the .then - because that's how Promise chaining goes

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.