Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Response for blob type #815

Closed
ecmel opened this issue Apr 4, 2017 · 10 comments

Comments

@ecmel
Copy link

@ecmel ecmel commented Apr 4, 2017

Hi,

When the responseType is blob, the error response is converted into a blob as well.

Is there a way to specify a different responseType for errors?

@rubennorte

This comment has been minimized.

Copy link
Member

@rubennorte rubennorte commented Apr 7, 2017

That isn't supported for the moment but you can implement it yourself specifying a custom transformResponse function.

@rubennorte rubennorte closed this Apr 7, 2017
@adriaanmeuris

This comment has been minimized.

Copy link

@adriaanmeuris adriaanmeuris commented Apr 21, 2017

I'm running into the exact same issue. Server returns a blob on success, on error a JSON object is returned containing error details.

The data returned in the transformResponse function is typed to the responseType (responseType blob: data is an [object Blob]), and there's no context available to know if the request succeeded or not.

An example how to know if the request succeeded and transform it to JSON if it didn't would be greatly appreciated.

@adriaanmeuris

This comment has been minimized.

Copy link

@adriaanmeuris adriaanmeuris commented Oct 6, 2017

@nickuraltsev since I can't re-open this issue, any guidance on how we can handle this situation?

@DaveSweeton

This comment has been minimized.

Copy link

@DaveSweeton DaveSweeton commented Oct 17, 2017

Same issue for me. I'd like to be able to use a solution like the one referenced here: https://stackoverflow.com/a/29039823

But it requires access to the onreadystatechange event of XMLHttpRequest, which isn't exposed. TransformResponse doesn't work since it's too late.

@fritx

This comment has been minimized.

Copy link

@fritx fritx commented Nov 1, 2017

+1 for this, I had a hack for it:

// Here is a hack, works well for me.
// You can put it into `transformResponse`, etc as well.
import fileDownload from 'js-file-download'

opts.responseType = 'blob' // <--- force blob at the beginning, anyway

res = await axios(opts)

let resBlob = res.data // <--- store the blob if it is
let resData = null

try {
  let resText = await new Promise((resolve, reject) => {
    let reader = new FileReader()
    reader.addEventListener('abort', reject)
    reader.addEventListener('error', reject)
    reader.addEventListener('loadend', () => {
      resolve(reader.result)
    })
    reader.readAsText(resBlob)
  })
  resData = JSON.parse(resText) // <--- try to parse as json evantually
} catch (err) {
  // ignore
}

// Now you have `resData` and `resBlob` at the same time.
// `resData` would be the normal data object,
// or the error object if `resBlob` is expected.

if (resData) {
  if (resData.error) {
    // handle error
  } else {
    // handle data
  }
} else {
  // handle blob
  fileDownload(resBlob, filename)
}

#448 (comment) looks like a full-typed version and more thoughtful but needs to take error-handling into account

@adriaanmeuris

This comment has been minimized.

Copy link

@adriaanmeuris adriaanmeuris commented Nov 1, 2017

@fritx works perfect, but indeed a bit hacky. @nickuraltsev any ideas how to improve this? thanks!

@farskid

This comment has been minimized.

Copy link

@farskid farskid commented Dec 24, 2017

@fritx Your workaround worked for me on a blob image sent as response. Thanks.

@aleen42

This comment has been minimized.

Copy link

@aleen42 aleen42 commented Sep 26, 2018

Using ArrayBuffer is another option, and do not need to solve the problem that synchrounsly read content of file blob.

const service = axios.create();

service.interceptors.response.use(
    response => {
        if (!/json$/gi.test(response.headers['content-type'])) {
            /** not json, like binary string */
            return response.data;
        }

        if (response.request.responseType === 'arraybuffer'
            && response.data.toString() === '[object ArrayBuffer]'
        ) {
            /** error response */
            const res = JSON.parse(Buffer.from(response.data).toString('utf8'));
        }
        
        /** handle res according to the JSON object */
        /** ... */
    },
    error => {/** handle error response status */}
);

const downloader = require('js-file-download');
server.post(url, params, {
    responseType: 'arraybuffer',
}).then(data => {
    downloader(data, 'xxx.csv');    
});
@nE0sIghT

This comment has been minimized.

Copy link

@nE0sIghT nE0sIghT commented Jan 14, 2019

In case of error response with json:

let axios = ...instantiate...;
axios.interceptors.response.use(
           response => { return response; },
           error => {
               if (
                 error.request.responseType === 'blob' &&
                 error.response.data instanceof Blob &&
                 error.response.data.type &&
                 error.response.data.type.toLowerCase().indexOf('json') != -1
               )
               {
                 return new Promise((resolve, reject) => {
                    let reader = new FileReader();
                    reader.onload = () => {
                        error.response.data = JSON.parse(reader.result);
                        resolve(Promise.reject(error));
                    };

                    reader.onerror = () => {
                        reject(error);
                    };

                    reader.readAsText(error.response.data);
                 });
               };

               return Promise.reject(error);
           }
       );
@sydinh

This comment has been minimized.

Copy link

@sydinh sydinh commented Oct 9, 2019

@nE0sIghT Worked well. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants
You can’t perform that action at this time.