552

This may seem stupid, but I'm trying to get the error data when a request fails in Axios.

axios
  .get('foo.example')
  .then((response) => {})
  .catch((error) => {
    console.log(error); //Logs a string: Error: Request failed with status code 404
  });

Instead of the string, is it possible to get an object with perhaps the status code and content? For example:

Object = {status: 404, reason: 'Not found', body: '404 Not found'}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Sebastian Olsen
  • 10,318
  • 9
  • 46
  • 91

16 Answers16

1047

What you see is the string returned by the toString method of the error object. (error is not a string.)

If a response has been received from the server, the error object will contain the response property:

axios.get('/foo')
  .catch(function (error) {
    if (error.response) {
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    }
  });
Nick Uraltsev
  • 24,607
  • 4
  • 25
  • 14
  • 28
    Can you explain the magic behind it automtatically turning into a string if I don't refer to the `response` property? – Sebastian Olsen Aug 25 '16 at 19:39
  • 26
    `console.log` uses the `toString` method to format `Error` objects. It has nothing to do with referring to the `response` property. – Nick Uraltsev Aug 25 '16 at 21:21
  • 8
    I'm still confused, is this spesific to error objects or? If I console.log an object, I get the object, not a string. – Sebastian Olsen Aug 25 '16 at 21:22
  • 8
    It depends on implementation. For example, node.js implementation of `console.log` [handles](https://github.com/nodejs/node/blob/master/lib/util.js#L430) `Error` objects as a special case. I cannot say how exactly it's implemented in browsers, but if you call `console.log({ foo: 'bar' });` and `console.log(new Error('foo'));` in the Chrome DevTools Console, you will see that the results look different. – Nick Uraltsev Aug 25 '16 at 22:17
  • 11
    Must be a native thing then. It's still strange though. – Sebastian Olsen Aug 25 '16 at 22:40
  • 1
    Will this work for status codes 50x ?? That is, if server is completely down ? – Dane Nov 27 '17 at 06:22
  • 3
    What about errors like 404? response is undefined in that case. – Manas May 24 '18 at 10:27
  • 3
    Late to the party, but FWIW `console.dir` will print the object and its properties – Chris Aug 15 '18 at 18:40
  • As ´console.log(obj)´ usually returns the object to the console, this is confusing. But hey, thanks for the solution - `msg = axiosError.response.data` worked like a charm within my response interceptor! – domih Nov 06 '18 at 10:22
  • 2
    With 401 errors the response property is `undefined`. – ndtreviv Jan 09 '19 at 16:38
  • 2
    You can do `console.dir` instead of `console.log` in Chrome to see the "inner" stucture of the error. This is the same trick that works with DOM elements -- it shows everything as object, instead of a "quick and pretty" (but sometimes misleading) representation. – Lazar Ljubenović Jan 04 '20 at 08:10
  • error object does not contain response object for non 200 errors. – Sebi2020 Sep 02 '20 at 18:38
  • Solved my problem but isn't it weird? Can anyone explain that? – Can PERK Sep 14 '20 at 14:49
  • @Sebi2020 - it does for me. – Davor Mar 31 '21 at 10:29
  • I am getting cant get status from undefined (referring to the response object as being undefined). Solved by saying error.status instead. – Abdullah Gheith Jun 07 '21 at 00:04
  • I was mistaken. I was getting error.response as undefined. It was because i had my interceptor setup wrong. .use must return the response and onrejected must return Promise.reject(error) – Abdullah Gheith Jun 07 '21 at 00:11
  • it is showing err.response undefined – Sunil Garg May 09 '22 at 12:23
71

With TypeScript, it is easy to find what you want with the right type.

This makes everything easier because you can get all the properties of the type with autocomplete, so you can know the proper structure of your response and error.

import { AxiosResponse, AxiosError } from 'axios'

axios.get('foo.example')
  .then((response: AxiosResponse) => {
    // Handle response
  })
  .catch((reason: AxiosError) => {
    if (reason.response!.status === 400) {
      // Handle 400
    } else {
      // Handle else
    }
    console.log(reason.message)
  })

Also, you can pass a parameter to both types to tell what are you expecting inside response.data like so:

import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
  .then((response: AxiosResponse<{user:{name:string}}>) => {
    // Handle response
  })
  .catch((reason: AxiosError<{additionalInfo:string}>) => {
    if (reason.response!.status === 400) {
      // Handle 400
    } else {
      // Handle else
    }
    console.log(reason.message)
  })
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Yan QiDong
  • 3,696
  • 1
  • 24
  • 25
  • 3
    I'm trying to get my team to switch over to Typescript for THIS kind of clarity. – GHOST-34 Dec 04 '20 at 04:13
  • this makes everything easier because you can get all the properties of the type with intellisense, so you can know the proper structure of your response and error – Ger Sep 13 '21 at 14:33
  • I don't think the non-null assertion here (on the line `if (reason.response!.status ...)`) is safe—if you get a 0 status code (e.g. network died before a response was returned), `reason.response` will be `undefined` and you'll get a TypeError there. – Ian Kim Jan 09 '23 at 16:35
27

As @Nick said, the results you see when you console.log a JavaScript Error object depend on the exact implementation of console.log, which varies and (imo) makes checking errors incredibly annoying.

If you'd like to see the full Error object and all the information it carries bypassing the toString() method, you could just use JSON.stringify:

axios.get('/foo')
  .catch(function (error) {
    console.log(JSON.stringify(error))
  });
danii
  • 5,553
  • 2
  • 21
  • 23
21

There is a new option called validateStatus in request config. You can use it to specify to not throw exceptions if status < 100 or status > 300 (default behavior). Example:

const {status} = axios.get('foo.example', {validateStatus: () => true})
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Dmytro Naumenko
  • 211
  • 2
  • 2
14

You can use the spread operator (...) to force it into a new object like this:

axios.get('foo.example')
    .then((response) => {})
    .catch((error) => {
        console.log({...error})
})

Be aware: this will not be an instance of Error.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Moses Schwartz
  • 2,857
  • 1
  • 20
  • 32
11

I am using this interceptors to get the error response.

const HttpClient = axios.create({
  baseURL: env.baseUrl,
});

HttpClient.interceptors.response.use((response) => {
  return response;
}, (error) => {
  return Promise.resolve({ error });
});
Tan
  • 342
  • 3
  • 11
10

In order to get the http status code returned from the server, you can add validateStatus: status => true to axios options:

axios({
    method: 'POST',
    url: 'http://localhost:3001/users/login',
    data: { username, password },
    validateStatus: () => true
}).then(res => {
    console.log(res.status);
});

This way, every http response resolves the promise returned from axios.

https://github.com/axios/axios#handling-errors

Emre Tapcı
  • 1,743
  • 17
  • 16
9

Whole error can only be shown using error.response like that :

axios.get('url').catch((error) => {
      if (error.response) {
        console.log(error.response);
      }
    });
Manik Verma
  • 161
  • 1
  • 5
7
const handleSubmit = (e) => {
e.preventDefault();
// console.log(name);
setLoading(true);
createCategory({ name }, user.token)
  .then((res) => {
   // console.log("res",res);
    setLoading(false);
    setName("");
    toast.success(`"${res.data.name}" is created`);
    loadCategories();
  })
  .catch((err) => {
    console.log(err);
    setLoading(false);
    if (err.response.status === 400) toast.error(err.response.data);//explained in GD
  });

};

See the console log then you will understand clearly

enter image description here

3
Axios. get('foo.example')
.then((response) => {})
.catch((error) => {
    if(error. response){
       console.log(error. response. data)
       console.log(error. response. status);

      }
})
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Vignesh
  • 174
  • 1
  • 5
  • While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained. – borchvm Jan 14 '21 at 07:11
  • I think I understand how this code works... its checking if response exist, then console.log... I think this is a good solution. – Jenuel Ganawed Mar 10 '22 at 23:01
  • Please don't post code-only answers. Future readers will be grateful to see explained why this answers the question instead of having to infer it from the code. Also, since this is an old question, please explain how it complements the other answers. In fact, it's essentially identical to the accepted answer. – Gert Arnold Jun 23 '22 at 18:44
3

With Axios

    post('/stores', body).then((res) => {

        notifyInfo("Store Created Successfully")
        GetStore()
    }).catch(function (error) {

        if (error.status === 409) {
            notifyError("Duplicate Location ID, Please Add another one")
        } else {
            notifyError(error.data.detail)
        }

    })
2

It's indeed pretty weird that fetching only error does not return an object. While returning error.response gives you access to most feedback stuff you need.

I ended up using this:

axios.get(...).catch( error => { return Promise.reject(error.response.data.error); });

Which gives strictly the stuff I need: status code (404) and the text-message of the error.

Bogdan Antone
  • 51
  • 1
  • 5
1

This is a known bug, try to use "axios": "0.13.1"

https://github.com/mzabriskie/axios/issues/378

I had the same problem so I ended up using "axios": "0.12.0". It works fine for me.

Dmitriy Nevzorov
  • 6,042
  • 1
  • 20
  • 28
1

You can put the error into an object and log the object, like this:

axios.get('foo.example')
    .then((response) => {})
    .catch((error) => {
        console.log({error}) // this will log an empty object with an error property
    });
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Mendy
  • 7,612
  • 5
  • 28
  • 42
0

An Axios Error has a lot of information, but if you do a regular console.log(error) you would just get a 'string message' generic error like: "Error: Request failed with status code XXX"

A Typescript solution to handle Axios Error and other errors.

axios.get('foo.example')
    .then((response) => {//...})
    .catch (error: any) {
        let errorResponse: any;

        // it is an AxiosError
        if (error?.isAxiosError) {
            const axiosError = error as AxiosError;
            errorResponse = axiosError.response; //all the info here
        } else {
            errorResponse = error; // it is not an AxiosError
        }

        console.log(errorResponse);
        throw errorResponse;
    }
Juanma Menendez
  • 17,253
  • 7
  • 59
  • 56
-1

It's my code: Work for me

 var jsonData = request.body;
    var jsonParsed = JSON.parse(JSON.stringify(jsonData));

    // message_body = {
    //   "phone": "5511995001920",
    //   "body": "WhatsApp API on chat-api.com works good"
    // }

    axios.post(whatsapp_url, jsonParsed,validateStatus = true)
    .then((res) => {
      // console.log(`statusCode: ${res.statusCode}`)

            console.log(res.data)
        console.log(res.status);

        // var jsonData = res.body;
        // var jsonParsed = JSON.parse(JSON.stringify(jsonData));

        response.json("ok")
    })
    .catch((error) => {
      console.error(error)
        response.json("error")
    })