Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fetch promises - return 500 internals server error

I am trying to handle 500 internal server errors inside fetch. If an internal error occurs, the server responds with a message. I want to extract that message.

const req = new Request(url, {
      method: node.method,
      mode: 'cors',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body),
    });
    fetch(req)
      .then((response) => {
        if (response.status === 500) {
          // res.json extracts the body from the response as a promise, chain
          // .then on it and throw an error to be caught in the lower catch.
          response.json()
          .then((json) => {
            const { message, stackTrace } = json;
            throw new ServerException(message, stackTrace); // note 1
          })
          .catch((error) => {
            return Promise.reject(RawException(error)); // note 2
          });
        } else {
          return response.json();
        }
      })
      .then((json) => { // note 3
        dispatch(stopLoading());
        dispatch(recieveResponse(typeOfRequest, json));
      })
      .catch((e) => {
        dispatch(stopLoading());
        dispatch(responseError());
        dispatch(showError(e.message));
      });
  };

My issue is that extracting the body of the response creates a new promise, and I am unable to reject the outer promise from the inner one.

Note 1 triggers the catch method of the inner promise. Inside catch, I have tried throwing another error but it doesn't seem to work. If I throw new RawException(error) on the second noted line, nothing happens and the then method on the third noted line triggers. If I return a rejected promise as I have in the code provided, then still triggers but json is undefined.

How do I do this?

like image 220
Brandon Dube Avatar asked Jan 18 '17 21:01

Brandon Dube


People also ask

How do you fix 500 Internal server error There is a problem with the resource you are looking for and it Cannot be displayed?

500 - Internal server error. There is a problem with the resource you are looking for, and it cannot be displayed. To resolve this issue, set the Enable 32-bit Applications to "False": Open the Internet Information Services (IIS) Manager.


1 Answers

The solution is not to nest promises, but to resolve/return the .then of the outer promise with the conclusion of the inner promise.

if (response.status === 500) {
  response.json()   // response.json returns a promise, we chose to do nothing with its
  .then((json) => { // conclusion
    const { message, stackTrace } = json;
    throw new ServerException(message, stackTrace); // note 1
  })
  .catch((error) => {
    return Promise.reject(RawException(error)); // note 2
  });
} else {
  return response.json();
}

Should become

if (response.status === 500) {
  return response.json() // return the result of the inner promise, which is an error
  .then((json) => {
    const { message, stackTrace } = json;
    throw new ServerException(message, stackTrace);
  });
} else {
  return response.json();
}

The else clause can be removed as well if that syntax is preferred. ESLint complains about the else being wasteful, but I perfer the way it makes the code's branching explicit.

like image 137
Brandon Dube Avatar answered Oct 28 '22 21:10

Brandon Dube