How can I get the response payload content?

I have the following axios call which is failing because of authorization issue. Hence, I want to display a message (maybe growl) on the screen once control reaches catch block. I can see the response payload in the Network tab but it’s not showing up when I am printing err.response as shown in the code below. The response payload shown in the browser looks like the following:

enter image description here

How can I grab the Response Payload value starting with NOT AUTHORIZED: .... inside catch block of axios?

const currentDate = new Date()
        let deliverDate = getFormattedDate(currentDate);
        const data = {
            downloadType: '1',
                dataDeliveryPojo: {
                      id: '0',
                      deliveredBy: JSON.parse(sessionStorage.getItem('loggedInUser')).personId,
                      deliveredToPersonId: JSON.parse(sessionStorage.getItem('loggedInUser')).personId,
                      deliverDate: deliverDate,
                      purposeId: 10,
                      companyId: 1234,
                      personId:JSON.parse(sessionStorage.getItem('loggedInUser')).personId
            },
          };

          /* 
           The response.data returned from Axios is a JSON string. So creating a Blob from that JSON doesn't produce the correct object. 
           Hence, make sure to tell axios to return blob
           From the Axios docs:
            // responseType indicates the type of data that the server will respond with
           // options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
           // browser only: 'blob'
           responseType: 'json', // default
          */              

         axios.post('api/fileDownload', 
          data,
          {responseType :'blob'}
         
          ).then((blob) => {
         
            let fileName = "";
            let disposition = blob.headers['content-disposition'];
            let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;   
            let matches = filenameRegex.exec(disposition);
            if (matches != null && matches[1]) { 
            fileName = matches[1].replace(/['"]/g, '');
            }
           
            const url = window.URL.createObjectURL(blob.data); 
            const a = document.createElement('a');
            a.href = url;
            a.download = fileName  
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);

           

            
    }).catch((err) => {

        console.log("Am I landing in catch block?");
        console.log(err.response);
      
    })  

The output of console.log(err.response); in the console is:

{
  "data": {},
  "status": 401,
  "statusText": "",
  "headers": {
    "cache-control": "no-cache, no-store, must-revalidate",
    "content-length": "84",
    "content-type": "text/plain; charset=UTF-8",
    "expires": "0",
    "pragma": "no-cache"
  },
  "config": {
    "transformRequest": {},
    "transformResponse": {},
    "timeout": 0,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1,
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "application/json;charset=utf-8"
    },
    "baseURL": "https://myserver.com/MyServices/",
    "method": "post",
    "responseType": "blob",
    "url": "https://myserver.com/MyServices/api/fileDownload",
    "data": "{\"downloadType\":\"1\",\"dataDeliveryPojo\":{\"id\":\"0\",\"deliveredBy\":\"TAN\",\"deliveredToPersonId\":\"TAN\",\"deliverDate\":\"2021-06-11\",\"purposeId\":10,\"companyId\":1234,\"personId\":\"TAN\"}}"
  },
  "request": {}
}

Are you sure you are not seeing something generated by the browser itself? I mean browsers understand that a status 401 is an unauthorized header and would probably show the NOT AUTHORIZED value you are seeing.

I ask because when you are printing the error.response that IS the payload. Without seeing the actual message, it is hard to say what data you are referring to. Is that data some how super sensitive to show us?

Actual message is just this one NOT_AUTHORIZED: risk level on the asset is Not Applicable so no decision is possible. But I am not able to see anything related to above message while printing err.response

What prints out when you just console.log(err)? Notice we are not looking at response property. In the console window you should then be able to see other properties and drill down into other pieces of data (if there are any)

It prints the following:

Error: Request failed with status code 401
    createError webpack:///./node_modules/axios/lib/core/createError.js?:16
    settle webpack:///./node_modules/axios/lib/core/settle.js?:18
    handleLoad webpack:///./node_modules/axios/lib/adapters/xhr.js?:59
    dispatchXhrRequest webpack:///./node_modules/axios/lib/adapters/xhr.js?:34
    xhrAdapter webpack:///./node_modules/axios/lib/adapters/xhr.js?:11
    dispatchRequest webpack:///./node_modules/axios/lib/core/dispatchRequest.js?:59
    promise callback*request webpack:///./node_modules/axios/lib/core/Axios.js?:51
    method webpack:///./node_modules/axios/lib/core/Axios.js?:71
    wrap webpack:///./node_modules/axios/lib/helpers/bind.js?:9
    handleDownloadClick webpack:///./src/main/js/components/RequestForm.js?:508
    onClick webpack:///./src/main/js/components/RequestForm.js?:466
    React 17
    unstable_runWithPriority webpack:///./node_modules/scheduler/cjs/scheduler.development.js?:653
    React 4

Surprisingly, if I print err.response.status or err.response, it doesn’t throws any error like above.

Hmmm… do you see anything in the console tab? Can you confirm that the status code is 401 on the response itself (look at the status column in dev tools, not the payload data)? It should tell you in the console. I say this because sometimes API designers will return a 200 OK but the status in the payload will be different. The idea behind this is that the service did successfully replied, even if the response was in error. I don’t agree with this philosophy, but it happens.

Are you referring to this? Please see screenshot below from Chrome:

yup, thanks. Well I am a bit dumbfounded too as to where that info is coming from. Did you check out your console tab? Look at the screenshot, second from the left after “Elements”. Anything showing up there?

Given its specific nature, and the fact that I can’t readily find that message when searching, it leads me to believe it is some specific custom message. That message doesn’t even show up with axios from what I can tell.

Yes, I did. It doesn’t shows anything except the console logs that I tried to print with err

Yes, the person who built the API call is sending that custom message (NOT AUTHORIZED:risk level on the asset is Not Applicable so no decision is possible). Sorry if it wasn’t clear before. Do I need to ask the person who built the API call to send it somewhere else in case of 401 scenario? I was hoping that since it is showing up in the Request tab, I would be able to retrieve it and display it on the screen to the user.

Oh if you are talking to the developer, ask them how that message is sent. Are they putting it in the body of the response? Is it a header? I mean you might as well ask them because it should be in the err.response if it was sent in the body of the response.

I checked the code myself and it looks like they are putting in the body .

In the tomcat server logs, I can see it getting printed like this

NOT_AUTHORIZED: risk level on the asset is Not Applicable so no decision is possible

It’s the same message that I am seeing in the Response tab inside Network tab.
image

Does it gives us some clue related to why it’s not showing up when I am printing in the console logs?

Looking at this stackoverflow post when I printed console.log(err.response.data); I saw the following:

Blob { size: 84, type: "text/plain" }

Do you think it might be because of Blob I am not seeing that response?

i got it working.

Based on the last answer listed here by Blaze 612 YT, I had to convert the Blob to string in the following manner.

let myblob = err.response.data;    

         let outurl = URL.createObjectURL(myblob);

            fetch(outurl)

            .then(res => res.text())

            .then(data => {

                console.log("Printing Not Blob");

                console.log(data)

            })

And I saw the following message in console log:

Printing Not Blob

NOT_AUTHORIZED: risk level on the asset is Not Applicable so no decision is possible