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

response status or response statusText is not available for 4xx/5xx series Http Status #1427

Closed
rswarup82 opened this issue Mar 18, 2018 · 17 comments

Comments

@rswarup82
Copy link

Hello All,

We are working on react-redux client application where axios library used for any XHR request. Sometimes backend service (Spring Boot REST endpoint) returns 4xx/5xx series HTTP response code. While we are trying to catch response status code from error object, found it is not available. Is there anyway HTTP response code can be extracted during error scenarios. We are using axios version 0.15.2.

Look forward to hear back from community.

Thanks

Context

  • axios version: e.g.: v0.15.2 or v0.16.2
  • Environment: e.g.: node v6.9.4, chrome 54, windows 7
@Axnyff
Copy link

Axnyff commented Mar 18, 2018

What is your code that is non working?
This works for me:

const axios = require('axios');
axios.get('/foo').then(null, error => console.log(error.response.status)); // 404

@rswarup82
Copy link
Author

rswarup82 commented Mar 19, 2018

Here is the sample code I am trying out to handle 4xx, 5xx, and 302 response code.

import axios from 'axios';

class XHRService {

  getWithParams(config, filter, request, receivedSuccess, receivedFailure) {

    return (dispatch, getState) => {

      if (request) {
        dispatch(request(filter));
      }

      const reqConfig = this.prepareConfig('get', config);

      // adding interceptor to find out response or error object structure.
      axios.interceptors.response.use(function (response) {

        console.log('inside axios response interceptor.');
        console.log('JSON.stringify(response) ---> ' + JSON.stringify(response));
        return response;
      }, function (error) {
        console.log('inside axios response interceptor catch block.');
        console.log('JSON.stringify(error) ---> ' + JSON.stringify(error));
        return Promise.reject(error);
      });

      return axios(reqConfig).then(response => {
        if (receivedSuccess) {
          dispatch(receivedSuccess(filter, response.data));
        }
      }).catch(function (error) {
        console.log('inside catch block.');
        if (error.response) {
          console.log(error.response.data);
          console.log(error.response.status);
          console.log(error.response.headers);
        } else if (error.request) {
          console.log(error.request);
        } else {
          console.log('Error', error.message);
        }
        console.log(JSON.stringify(error));
      });
    }
  }

  // code related to prepareConfig(....)

  // some shared code.
}

Let me know your thoughts on the same.

@pavlovalor
Copy link

pavlovalor commented May 17, 2018

Ok. So I found out that error.response will be null if there is error code together with actual content. That's confusing.

  • axios version 0.18

@tebs1200
Copy link

I'm also experiencing this issue.

On certain 4XX errors, my API contains a payload in the body with further information on what went wrong. When my 400 response has a body, error.response is null.

If you check out section 6.5 of RFC 7231 you'll see that for several codes, the server should be providing response bodies in many situations (403, 406). At the moment, I'm unable to access the response code in the catch which is creating issues.

@ToKaDev
Copy link

ToKaDev commented Jun 28, 2018

I'm also have this issue. I like to show some information about the error reason to the user. But the statusText property is always undefined.
But it seems that the statusText is also undefined when I use the fetch function.

(react-native 0.55.4 with axios 0.18.0)

@tebs1200
Copy link

I tried to reproduce this in a basic unit test by adding the following to test/unit/adapters/http.js:

  testErrorWithJSON: function (test) {
    var data = {
        firstName: 'Fred',
        lastName: 'Flintstone',
        emailAddr: 'fred@example.com'
    };

    server = http.createServer(function (req, res) {
      res.setHeader('Content-Type', 'application/json;charset=utf-8');
      res.statusCode = 403;
      res.end(JSON.stringify(data));
    }).listen(4444, function () {
      axios.get('http://localhost:4444/').catch(function (err) {
        console.log('running 403 test');
        test.equal(err.response.status, 403);
        test.done();
      });
    });
  },

The test passed and the expected status code was available on err.response.

I also added the following to test/specs/requests.spec.js:

  it('should set error status when rejecting with body', function (done) {
    var response;

    axios('/api/account/signup', {
      username: null,
      password: null
    }, {
      method: 'post',
      headers: {
        'Accept': 'application/json'
      }
    })
      .catch(function (error) {
        response = error.response;
      });

    getAjaxRequest().then(function (request) {
      request.respondWith({
        status: 403,
        responseText: '{"error": "BAD USERNAME", "code": 1}'
      });

      setTimeout(function () {
        expect(typeof response).toEqual('object');
        expect(response.status).toEqual(403);
        done();
      }, 100);
    });
  });

This also passed, so error.response seems to be getting set correctly in the test cases. I'll keep looking into this a bit more.

@tebs1200
Copy link

While watching the Jasmine tests running and seeing that the node unit tests pass, I thought It would be prudent test my web application in different browsers.

Turns out that in Chrome, the code runs as expected - error.response is there and I can access the status code without issue.

Using Safari, error.response is null. Looks like Safari responds differently to an actual remote 4XX response than it does to the mocked response from jasmine-ajax. Can anyone else confirm if they are seeing the issue only in Safari?

@blahmonkey
Copy link

blahmonkey commented Aug 28, 2018

Same issue -- backend sends a HTTP 400 with a response body. Axios code does not catch() it as an error, and instead returns a null response object. So I cannot handle different HTTP 400 cases and respond to the user with more nuanced feedback on what they did wrong

Code -

return this.axiosInstance.post(this.confirmEmailUrl, postData).then(res => {
console.log(res) // Returns null
return res
})

Context
axios version: v0.18.0
Environment: Chrome 68.0.3440.106, OSX High Sierra

@Andrinoid
Copy link

Andrinoid commented Sep 12, 2018

I had the same issue. I found that if there is an error either from the server or in the .then function axios will return an error object and the response must be accessed on err.response.data
It's confusing because you can not console log the error object to see the actual response.
This worked for me

axios.post('SOME_ENDPOINT').then(res => {
      console.log(res.data)
    }).catch(err => {
      console.log(err.response.data)
    })

@stereonom
Copy link

Using Safari, error.response is null. Looks like Safari responds differently to an actual remote 4XX response than it does to the mocked response from jasmine-ajax. Can anyone else confirm if they are seeing the issue only in Safari?

@tebs1200 yeah, we're having the same problem with safari. chrome works for us.

@blahmonkey
Copy link

This works for me
#1143 (comment)

-- you get e.g. 403 as a valid response. Then just filter by status code in your then() handler.

@AllainPL
Copy link

This looks like a design decision of @axios team might be worth revisiting. Probably by now this issue is ready to be closed. @emilyemorehouse

@ussefshahid
Copy link

What is your code that is non working?
This works for me:

const axios = require('axios');
axios.get('/foo').then(null, error => console.log(error.response.status)); // 404

It works, ☺

@brasrox
Copy link

brasrox commented Jul 11, 2019

same issue here, when i recve 404 or 403 error, the statusText is undefined ( server response with some text explaining the error)
the status code still ok, just the message on statusText are undefined
{
status: 403
statusText: undefined
}

@vitpankin
Copy link

For me something weird is happening. When request succeeds I get payload.status and all the stuffload of props inside payload. But if request fails I can access status only in payload.response.status and all the fields happens to be inside response object. How the holy moly this suppose to work? Why I have to search for status field in different depending on request results?

@chinesedfan
Copy link
Collaborator

As far as I know, users can solve it by setting their own config.validateStatus function, just as #1143 (comment) mentioned.

Closing this issue first, because it mixes lots of people problems, but feel free to open a new one if it is still there.

@thanhluantl2304
Copy link

thanhluantl2304 commented Mar 27, 2020

@brasrox any update on this? StatusText was still undefined �although i have passed it through api request. Still stuck at the moment! So sad!

@axios axios locked and limited conversation to collaborators May 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests