0

I have an error handler in my Nodejs express backend that catches some errors and sends it to the client:

res.status(error.status|| 500).json({
      status: error.status||500,
      message: 'MY CUSTOM ERROR MESSAGE',
      stack: error.stack
})

I have been using jquery ajax for the longest time and have always been able to get the value of the message obtained from the backend like this:

$.ajaxSetup({
    error(jqXHR, exception) {
      $('#divSubmitButtonSpinAnimation').addClass('d-none');

      console.log(jqXHR);
      console.log(exception);
      $.toast({
        position: 'top-right', /** top-left/top-right/top-center/bottom-left/bottom-right/bottom-center - Where the toast will show up * */
        dismissible: true, /** true/false - If you want to show the button to dismiss the toast manually * */
        stackable: true, /** true/false - If you want the toasts to be stackable * */
        pauseDelayOnHover: true, /** true/false - If you want to pause the delay of toast when hovering over the toast * */
        title: jqXHR.statusText,
        subtitle: jqXHR.status,
        content: (jqXHR.responseJSON) ? jqXHR.responseJSON.message : 'Unspecified Error',
        type: 'error',
        delay: 5000,
      });

     
      return false;
    },
  });

However, I am now working on ability to upload file and I ran into problems when using jquery ajax so I have decided to start using the await fetch api. I have got the most part working except, I can no longer read the value of the response.message as it is undefined.

const response = await fetch(
      '/getStudentInfo',
      {
        headers: {
          Accept: 'application/json',
        },
        method: 'POST',
        body: formData,
      },
    );
    if (response.status === 200) {
      return response.json();
    }

    console.log(response.message)

response.message is undefined but response.status is 500 and response.statusText is "Internal Server Error" which is expected as I am sending error 500 from the server.

goxarad784
  • 395
  • 6
  • 17

2 Answers2

1

You still need to call response.json() to access the message in the response body, even when the http status is not 200.

const response = await fetch('/getStudentInfo', {
  headers: {
    Accept: 'application/json',
  },
  method: 'POST',
  body: formData,
});
const data = response.headers.get("content-type")?.startsWith("application/json"))
  ? await response.json()
  : await response.text();

if (response.ok) {
  console.log(data);
} else {
  console.error(data.message);
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

So it looks like I have to convert the reponse to json to get the message property. So what I did is something like this.

 const response = await fetch(
      '/createInspectionDetail',
      {
        headers: {
          Accept: 'application/json',
        },
        method: 'POST',
        body: formData,
      },
    );
    if (response.status === 200) {
      return response.json();
    }

    const data = await response.json();

    createGenericMessage('Error', data.message, 'danger');

And apparently this is needed because reponse itself is another promise that arrives as soon as the header arrives so we still need to await that for further information:

Read more detail here:

Why does .json() return a promise?

goxarad784
  • 395
  • 6
  • 17