1

I tried to check if the status of my request is 200 (OK), but I do not know how to do these things together because the first and second .then, are not "like each other":

function f(path) {
    await fetch(path)
            .then(response => {
                // console.log(response.status);
                if (response.status != 200) {
                    throw response.status;
                } else {
                    // do something
                }
            })
            .then(response => response.json())
            .then(...method for the response.json()...)
            .catch(error => {
                // print some error message
            }
}
  • The second then failed and returned error.

I have a problem when I throw that.

It prints to the error to the console (when I check by changing the path to wrong path and I want to see if I treat errors).

what can I do?

2
  • 1
    Please add a minimal reproducible example (which includes at least the error thrown and depending on the error the content of the response) which shows the actual problem Commented May 30, 2020 at 12:19
  • 2
    you need to return response in the first then so that the second then is able to use it Commented May 30, 2020 at 12:21

5 Answers 5

2

You're checking it correctly in your first fulfillment handler (then callback), although I'd just use !response.ok. You don't usually need the status in the subsequent handlers.

But the problem with your first fulfillment handler is that it's not returning anything, so the subsequent fulfillment handler only sees undefined. Instead, return the promise from json():

function f(path) {
    fetch(path)
        .then(response => {
            if (!response.ok) {
                // Note: Strongly recommend using Error for exceptions/rejections
                throw new Error("HTTP error " + response.status);
            }
            return response.json();
        })
        .then(data => {
            // ...use the data here...
        })
        .catch(error => {
            // ...show/handle error here...
        });
}

Note that you can't use await in a traditional function, only in an async function. But you don't need it if you're using .then and .catch. I've removed it above.

If for some reason you wanted the status in subsequent fulfillment handlers, you'd have to return it from the first fulfillment handler. For instance:

function f(path) {
    fetch(path)
        .then(response => {
            if (!response.ok) {
                // Note: Strongly recommend using Error for exceptions/rejections
                throw new Error("HTTP error " + response.status);
            }
            return response.json().then(data => ({status: response.status, data}));
        })
        .then(({status, data}) => {
            // ...use `status` and `data` here...
        })
        .catch(error => {
            // ...show/handle error here...
        });
}

In that, I've used a nested fulfillment handler on the promise from json(), and then returned an object with status and data on it.

Sign up to request clarification or add additional context in comments.

Comments

1

You need to return in your then chain, which at a glance appears to be one too many. Check out the following example...

fetch(path)
  .then(r => r.ok ? r.json() : Promise.reject('oops')) // .statusText, etc
  .then(r => {
    // [...]
  })
  .catch(e => console.error(e)); // oops

Comments

1

a) I don't think you need await keyword since you're using .then() chaining.

b) You have to return something from the first then so as to get that in the next .then()

function f(path) {
await fetch(path)
        .then(response => {
            // console.log(response.status);
            if (response.status != 200) {
                throw response.status;
            } else {
                // do something
                 // After doing what you need return the response
                return response
            }
        })
        .then(response => response.json())
        .then(...method for the response.json()...)
        .catch(error => {
          // print some error message
          }
}

Comments

1

Actually, it's not clear what your function has to do. But I think your sturggle comes from not fully understanding how promises chain works. For that, I'd recommend familiarizing yourself with this article, it helped me a lot :)

So back to your function. The elegant solution is adding simple "tap" function, that allows you to do some stuff with current response, but still it passes response further for other .then chains.

Here's the tap function:

const tap = (callback) => (value) => (callback(value), value);

And finally how you can use it:

function f(path) {
  fetch(path)
    .then(
      tap((response) => {
        if (response.status !== 200) throw new Error(response.status);
      })
    )
    .then((response) => {
      // do other stuff
    })
    .catch((error) => console.error(error));
}

Comments

0

The number of browsers that support fetch but don't support async/await is now very small, so you may be better off using this simpler syntax first, and then transpiling for legacy browsers along with your shims for fetch.

Your function becomes:

try {
    const response = await fetch(path);

    // console.log(response.status);
    if (response.status != 200) {
        throw response.status;
    } else {
        // do something
    }

    const parsed =  await response.json();

    // do something with parsed
}
catch(error) {
    // print some error message
}

This new syntax makes it much easier to deal with errors in the different then actions:

const response = await fetch(path);

// console.log(response.status);
if (response.status != 200) {
    throw response.status;
} else {
    // do something
}

let parsed; // Will hold the parsed JSON
try {    
    parsed =  await response.json();
}
catch(error) {
    // Deal with parsing errors
}

try {
    // do something with parsed
}
catch(error) {
    // Deal with errors using the parsed result
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.