Search code examples
reactjstypescriptasp.net-coreerror-handlingfetch

How to handle bad request in fetch()


I know this is a basic and often recurring issue, but I am still unable to make it work.

I have the following code

handleAdd = (event: any): void => {
        
    // ...
        
    // create new task
    try {
          // send data to backend
          fetch(`/api/tasks?name=${name}&priority=${priority}`, { method: 'post' })
                .then(response => { if (!response.ok) {  
                       throw new Error('error => how to get bad request message here?') } })
    }
    // handle exception
    catch (e) {
          console.log(e);
          this.setState({
               isError: true,
               errorMessage: e.message
          });
    }
}

the API returns 400 with some error message

enter image description here

but in the browser I get

enter image description here

So I have two questions

  • Why the throw new Error() in fetch does not goes to catch(e) {} method (if the error is outside fetch function, it works well)? How to rewrite this line to get into catch method? I think it has something to do with the Promise object?
  • How to get the bad request message from response object?

update, working solution


fetch(`/api/tasks?name=${name}&priority=${priority}`, { method: 'post' })
    .then(response => {
        if (!response.ok) {
                  
            response.text().then(function (text) {
                throw Error(text);
            }).catch((e) => {
                this.setError(e.message);
            });

        }
    })
  • how to get response.text() into the Error exception?

Solution

  • when using promises, you can choose between chaining your promise with then/catch or using async/await.

    if you are chaining promise you should chain with a catch:

    handleAdd = (event: any): void => {
        // send data to backend
        fetch(`/api/tasks?name=${name}&priority=${priority}`, { method: 'post' })
            .then(response => { if (!response.ok) {  
                  throw new Error('error => how to get bad request message here?') } }
            ).catch((e) => {
                console.log(e);
                this.setState({
                  isError: true,
                  errorMessage: e.message
                })
            });
    }
    

    if you prefer you can change your function to async/await. with that you would use a try/catch block:

    // mark your function as async
    handleAdd = async (event: any): void => {
    
      try {
        // await your fetch response
        const response = await fetch(`/api/tasks?name=${name}&priority=${priority}`, { method: 'post' })
        if (!response.ok) {  
          throw new Error('error => how to get bad request message here?')
        }  
      }
      // handle exception
      catch (e) {
        console.log(e);
        this.setState({
              isError: true,
              errorMessage: e.message
        });
      }
    }