Axios: Axios catch error returns javascript error not server response

Created on 17 Jun 2017  ·  87Comments  ·  Source: axios/axios

Im trying to catch validation errors from the server.

Code:

axios.post('/formulas/create', {
       name: "",
       parts: ""
})
.then( 
    (response) => { console.log(response) },
    (error) => { console.log(error) }
);

Console log output

Error: Request failed with status code 422
    at createError (app.js:6765)
    at settle (app.js:29489)
    at XMLHttpRequest.handleLoad (app.js:6600)

Network tab output
{"name":["The name field is required."],"parts":["The parts field is required."]}

I should be seeing an object that contains JSON form validation as that is the response in my network tab, i seem to get the JS catch output?

Also tried the following:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error)
});

Same result

More people seem to have the same problem using the same enviroment as me here.
https://laracasts.com/discuss/channels/vue/issues-with-axios-catch-method

  • Axios version: ^0.16.2
  • VueJS 2.3.4
  • Vue-template-compiler 2.3.4
  • Laravel-mix
  • Environment: node v6.4.0, chrome 58, Mac OSX 10.12.4

Most helpful comment

I have exactly the same environment. Try this:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error.response)
});

Modify from console.log(error) to console.log(error.response) in catch.

You can also use a global interceptor and reject only the error.response. The problem is when the console.log tries to output the error, the string representation is printed, not the object structure, so you do not see the .response property.

All 87 comments

I have exactly the same environment. Try this:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error.response)
});

Modify from console.log(error) to console.log(error.response) in catch.

You can also use a global interceptor and reject only the error.response. The problem is when the console.log tries to output the error, the string representation is printed, not the object structure, so you do not see the .response property.

In case anybody is wondering how to reject only the response property, here's how to do it:

axios.interceptors.response.use((response) => {
    return response;
}, function (error) {
    // Do something with response error
    if (error.response.status === 401) {
        console.log('unauthorized, logging out ...');
        auth.logout();
        router.replace('/auth/login');
    }
    return Promise.reject(error.response);
});

The important part is return Promise.reject(error.response);

This yields the same result incase if the above solution messes up your JS file syntax while indenting or minifying :)

.post('ajax/register/otp', this.registerData)
.then(function (response) {
       return otpSent(response)
})
.catch(function (error) {
      console.log(error.response);
 });

@gopal-g that's undefined for me.

Well @pedro-mass in that case there might be no response from server side. in my scenario my response was JSON when error occured I could get the response using error.response

@gopal-g If I'm watching the Network tab in dev tools, I can see the response. It's a 401 if that makes a difference.

I have the same error with @pedro-mass 's.

here is my code

async function test () {
try {
  let res = await axios.get('/xxxxx/xxxx')

} catch (e) {
  console.log(e.response) // undefined
}
}

using "error.response" does not work, for me. The problem occurs when I disconnected the database server and my web server returned error 500.

Network tab in dev tools

response code: 500
response body:

{
  "error": {
    "statusCode": 500,
    "name": "Error",
    "message": "read ETIMEDOUT",
    "code": "ETIMEDOUT",
    "errno": "ETIMEDOUT",
    "syscall": "read",
    "stack": "Error: read ETIMEDOUT\n    at exports._errnoException (util.js:1050:11)\n    at TCP.onread (net.js:582:26)"
  }
}

chrome console error:

Uncaught (in promise) Error: Request failed with status code 500
    at createError (createError.js:15)
    at settle (settle.js:18)
    at XMLHttpRequest.handleLoad (xhr.js:77)

version

"axios": "^0.15.3"

There is a catch in catch: if the error occurs before the request is made, then in catch you will not have the err.response property, because... well... there is no response. So, the catch will catch any error. The same applies in the situations like the one from @fabiorecife when there is no response because of a network failure. Do not treat the err as a HTTP error because this is not always the case.

@alsofronie so what is the preferred method of handling (distinguishing one from another) for example preflight failures like 413?

I'm getting a similar issue - Chrome devtools is showing a 401, the response is {"message":"Identity token has expired"} and I am catch( (error) => {...}) - but error.response blank. I am wondering if this is because the preceding OPTIONS call associated with the GET has a status of 200. What to do in this case and where is the right place to retrieve the 401 status code?

@robbiemu I think its already documented: https://github.com/axios/axios#handling-errors

@mrchief thanks for this, good to go over it again. In my case, this solution has works in most cases but the current problem I am experiencing is that the error.response object is present, but fields are undefined, any calls to values inside the response object result in an error.

@paolavness I'd suggest to open up a new issue instead of commenting here. Not many watch closed issues. Or maybe even ask it on StackOverflow.

@mrchief Ah this is closed, thanks for pointing that out. will do.

I had the same issue. Ultimately, I changed the error code from 401 to 403 and everything worked as I expected it to. I'm guessing the reason for the empty error object and resulting javascript error has to do with this statement that I found in the documentation for 401 errors:

"[A 401 error] response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource."

So if you are going to utilize a 401 error, you must include a www-authenticate header field. If you don't want to do this, just use a 403 error.

Good morning guys, I had this issue, however, I fixed it changing my apache configuration to enable cors on my server. Have a look at link below

https://enable-cors.org/server_apache.html

You can debug all response only with console.log(JSON.stringify(error))

axios.post(url)
.then((response) => {
// something
})
.catch((response) => {
if (response.status == undefined) {
alert('unauthorized')
}
})

I had exactly the same problem described by @fabiorecife . I solved it but it is not the most elegant solution and I do not understand why this is needed.

.catch(error=>{
let errorObject=JSON.parse(JSON.stringify(error));
console.log(errorObject);
dispatch(authError(errorObject.response.data.error));
})

This produces the expected results in the errorObject variable.

@petruscurtu I have the same problem! It dose not work for me!
image
I don't khnow why it throw 'no Access-control-allow-origin', but the server has set it! The response header is ok

image

Resolved. The auth api was not responsing the right header that must have the Access-control-allow-origin

@luxueyan I do not know what the problem could be since I do not know how you handle CORS on your server. As far as axios is concerned, I can see a config and request object in your console output. I think that you should check that output. It might be related to the format of the response your server is sending back.

@luxueyan It seems that you had your Access-control-allow-origin set up for http://localhost:8081 (assuming this is set on the server with this address http://10.31.143.32:8080?) Can you check what is the URL you're running this project from? Is it http://localhost:8081? If it is not, even if the port number is different, then it is violating the CORS domain rules.

@petruscurtu The output is 'JSON.parse(JSON.stringify(error))' in interceptor of response. There has not response property

@chiefie I am sure that 'Access-control-allow-origin' setting is ok since other ajax api can response right content!Only the capcha code api go wrong。 when it is expired, it response error with 478 status and axios can not get the response body!

Update! It was the server api error, it didn't have cors settings in header. Now work well.

Thanks @juliano-barros it was because of the cross-origin. Now all my ajax requests works just fine.

This raw error is thrown whenever server is unreacheable/CORS invalidated.
error.response will just be undefined.

I just created an IntegrationError which contains message, status and response data... but always following the same structure. This way I can decouple axios/raw error from my handlings.

Axios guys, this should be a HTTP error I think... including an error.response.
This can be checked as above

Yesterday was the one-year anniversary of this issue. Will it ever get "fixed" or is it considered to be a "non-issue" at this point?

@frostshoxx So i think this is a "non-issue". While I am experiencing the same problem as everyone else, i now understand what is happening and I can see that this isn't a bug or issue, but just the way the world works.

For everyone that is confused (and in celebration of this issue turning one year old) let me explain what is happening and how to get your server response.

How Did you End Up Here?

There are many reasons you might encounter the .catch() wasteland. Sometimes Axios encounters an error early on in the request. This sometimes happens with CORS requests. When Axios OPTIONS isn't available, than Axios panics and sends you to .catch() before it actually gets a response from the server, so the response isn't available in these cases.

Some of you might say, "No, i see it in DevTools, so the response came back!". This isn't always true because sometimes Axios will kick off an HTTP request, experience an error, abort itself and send you to .catch() before the server responded back. A few milliseconds after Axios runs the .catch() function than your server might come back with a response, which shows up in DevTools because it is still listening for the response. However, Axios is long done at this point, so the response wasn't available because it didn't exist at the time that Axios initiated the .catch() function.

Those of you that get a message about a 4XX or 5XX error from the server, are in luck! There is usually a response from the server available to you because in order to get this error, Axios had to wait around for the full server response. In these cases, Axios sends you to .catch() with the response but it wraps the response in its own error object that it creates on the fly.
So if you are getting 5XX or 4XX errors, than you probably have the server response available to you, but it is buried DEEP!

Try error.response.data.data.message. This is confirmed to work for Laravel API requests that return server errors.

Non-Laravel users -- You will at least need to go error.response.data to get to the core response from the server, but most servers than wrap their responses in another data{} object requiring you to go a layer deeper, and then finally access the response property you want like .message from there.

But I Did Console.Log and It Contains No Response!

Yeah i know, but just try to output error.response.data anyway just to humor me.

For some reason Axios modifies the output of console.log(error) on the error object. I am not sure why they do this, but if you instead write console.log(JSON.stringify(error)) than you will see the whole object in all its glory.

This is serialized JSON which gets hard to read after about 2 layers deep. So you should copy the full thing and paste it into a JSON prettifyer to explore the error object's structure.


If you are getting a 500 error or a 400 type error (or really any server supplied error code) in Axios, then that means that the request completed and that the server's response is available to you!

The problem is that it's super deep, and because Axios modifies the output of our console.log(error) that most people do to see the error{} object, most people don't know that it exists. But it's there!

@VSG24 man!! that's a life-saving answer :D

fwiw, JSON.stringify(error) bombs in 0.18.0 due to circular references.

I set up an interceptor which gives me server response on error

axios.interceptors.response.use(
  response => {
    // do someting on response
    return response
  },
  error => {
    // do someting on errir
    return Promise.reject(error.response.data) // => gives me the server resonse
  }
)
    try {
      const { data } = await htttp.post(login, payload)
      // do someting with data
    } catch (e) {
      console.log(e) // server response data
    }

@alimirayman It seems to work fine if we don't have to keep an eye on every request. But, when you have to track every request, it's not reasonable to have an error handler repeated in every location in my code. Unless I understood wrong ( wich may be the case ), axios should'nt have to make sure the server has returned an error before it throws an error ?

@hhowe29 use circular-json

I found this thread like many others and I'm using axios with vue.js and vuex modules.

My vuex module action catches the axios error and runs commit(ERROR_HAPPENED, error) to run the ERROR_HAPPENED mutation of the vuex module. But the error arrives without its response property resulting in error.response being undefined if I attempt to set the response to a vuex state.

If I console.log(error.response) in the action, before the commit(), I can see the response. So it's being mangled by vuex most likely.

Either commit(ERROR_HAPPENED, error.response.data) or check if it's a 401 in the action and run some other commit depending on the status code. Because this mangling only happens with a 401 code. Other errors like 404 or 500 are passed through to my mutations.

Not mangled. Vuex does not mangle this, not even by bug.
Some kinds of errors, mostly inside Axios interceptors, cause this to not be exposed.

Some update ?

@AllanPinheiroDeLima sorry for the late reply but I don't think anyone writes intercepter on each and every single location of anyone's code. We write intercepter one time on a code base and use it as a helper class, that's number 1. Number 2, the initial query was they did not get _server error response_, instead, they got the _javascript error_ in the try catch block. there were 2 solution one to change the way server responded error or the way frontend catched error. axios error intercepter is basically acts as a middleware to solve that issue if you don't want to change your ways to code or change a large code base.

Yeah, I agree. I found a solution to this problem making the integration into my own server instead using raw keycloak. This way I could intercept the error in the server and then send a legible one to the front end. I think that’s the only way to solve this kind of issue for now :)

I'm having the same problem yet. Using in Axios interceptor console.log('interceptors', JSON.stringify(error)) i get this log interceptors {"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"},"method":"post","url":"http://localhost:5000/api/autenticacao/login","data":"{\"siglaInstituicao\":\"NEAS\",\"usuario\":\"emersoncpaz\",\"senha\":\"belle1903\"}"},"request":{}} but chrome devtools Response i have the correct response from the api : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) How to get this response from axios?

Any reason 5xx errors are not handled by catch block (doesn't return a response object)? Status code 502 appear in DevTool console but doesn't get handled by Axios.

This worked for me (with laravel abort helper: abort(500, 'message'))
```
.catch(error => {
console.log(error.response.data.message);
});

```

Does anyone one have a full working example other than snip of code saying this worked? Snip of 1 line does not help much if you have no idea who they were referring to in this thread, where they put that snip of code, what the final working code looks like?

I am trying to catch the error in the inerceptor and based on the error code either end the request there with redirect if 401 to login, or if its 422 let the request go back to the calling component to allow updating of the form errors.

Any ideas?

I am using Nuxt axios and my onResponseError interceptor looks like:

$axios.onResponseError(error => {
    const code = parseInt(error.response && error.response.status)
    console.log(code, 'Axios onResponseError')
    console.log(error.response.status, 'status')
    console.log(error.config, 'config')
    console.log(error.response, 'response')
    // Do something with response error
    if (error.response.status === 401) {
      console.log('unauthorized, logging out ...')
      app.$auth.logout()
      redirect('/login')
    }
    if (code === 400) {
      // redirect('/400')
      console.log(`400 onResponseError`)
    }
    if (code === 408) {
      console.log(`A timeout happened on url onResponseError`)
    }
    if (code === 418) {
      console.log(`A teapot onResponseError`)
    }
    if (code === 428) {
      console.log(`428 onResponseError`)
      // redirect('/login')
    }
    return Promise.reject(error)
  })

And a sample call would look like:

async postRecord (clear = false) {
      try {
        const { r } = await this.$axios.$post(this.endPoint, this.formData)
        console.log(r, 'response')
        // do something with response
      } catch (e) {
        console.log(e, 'error in crud') // server response data
        // i should never get here if error since the interceptor should kill the request if 401
       // for testing this request is returning a 401
      } finally {
        this.submitted = false
      }
    },

Thanks,
Dave

When there is no internet, the error.response is undefined - is this the best way?

I get error in plain text, I had to use the following to convert error in an object.

var errorObj = JSON.parse(JSON.stringify(error));

This is down to the server and not axios, have you tried digging into the
error.response.status, if it's undefined then you know it's an Internet
connection issue or a syntax error in your JS

On Wed, 2 Jan 2019, 15:40 Ibrahim Azhar Armar <[email protected]
wrote:

I get error in plain text, I had to use the following to convert error in
an object.

var errorObj = JSON.parse(JSON.stringify(error));


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/axios/axios/issues/960#issuecomment-450896476, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AEETt2r3bt2QCixDlzh4fZvWp_1rPkxuks5u_NMEgaJpZM4N9Ljl
.

@kgrosvenor I am putting the server script to sleep and wait for axios to trigger timeout. I believe server at this point is not responding hence triggering the callback in axios.

I am getting the right error message however console shows it in plain text, hence it seems only the formatting issue, which does not seem related to the server.

If it is, I am trying to understand what in server could be causing this?

You are most likely hitting a timeout then, try checking if 'response' exists in the error

axios.get()
.then(function(done) {
   //fine and can get done.data
})
.catch(function(err) {
  //catch the error, check it has a response object with lodash 
  if(_.has(err, 'response') {
     console.log(error.response.status);  
     console.log(error.response.data);
 } 
 else {
    console.log("Most likely a server timeout or an internet connection error");
    console.log("error response property is undefined")
 }
}); 

Java programmer sends me error message with 500 error and I can't handle that message. So I'm asking him to return 200 status with error message in response but he's angry at me and says that his HTTP client sees all the messages with 500 status. He thinks that I'm stupid because I can't find error message with 500 status. How do I explain him that axios doesn't handle 500 error message?

Java programmer sends me error message with 500 error and I can't handle that message. So I'm asking him to return 200 status with error message in response but he's angry at me and says that his HTTP client sees all the messages with 500 status. He thinks that I'm stupid because I can't find error message with 500 status. How do I explain him that axios doesn't handle 500 error message?

Actually, you must be able to handle error with status 500, you can check for http status in response and decide on how to handle it in the client side. This is already documented in this link (https://github.com/axios/axios#handling-errors)

Here is how I catch error 500 from server, and it works for me.

.catch(function (error) {
    var errorObj = JSON.parse(JSON.stringify(error));
    console.log(errorObj);
    if (errorObj.code == 'ECONNABORTED') {
        alert('Connection timed out.');
    }
});

You can handle 500 status regardless, but pretty bad practice to return it on purpose from the server side in my opinion...

I am also getting error.response undefined then I try below code.

axios.interceptors.response.use(function (response) {
  return response;
}, function (error) {
  // Do something with response error
  let {response} = error;
  // response?.status === 401 es7 way.
  if (response && response.status === 401) {
    // Do logout;
    // Redirect to login;
    return Promise.reject(error.response);
  } 
  else if (error.response){
    // Do something.
    console.log('some API_CLIENT error');
    return Promise.reject(error.response);
  }
 return Promise.reject(error);
});

This is too bad, error handling is important.

How is going now? I am still experiencing the same problem with version 0.18.0!

same problem to me: @nuxtjs/axios v5.0.0

It is a bug

Daniel Stern notifications@github.com 于 2019年2月28日周四 04:39写道:

Let me summarize this discussion.

tl;dr:
EVERYONE Being unable to catch HTTP errors is a problem.
DEVELOPERS Being unable to catch HTTP errors is not a problem.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/axios/axios/issues/960#issuecomment-468020991, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAN8CbMHohyuSZHYlcieD_5yUqizpkSYks5vRuzygaJpZM4N9Ljl
.

You have to mention this issue in the README please, very helpful. Thanks!

https://github.com/axios/axios/issues/960#issuecomment-320659373

Agreeing with other posters. Having an object with unpredictable structure given to catch depending on the point where the error happens isn't great. Both error.response and JSON.stringify(error) can themselves error out depending on the cause. The suggested approach at https://github.com/axios/axios#handling-errors isn't exactly enlightening on this either.

Having to do all this acrobatics to return a freaking error message is embarrassing in 2019. It would've been embarrassing in 1990. Seriously JS people, step up your game. Learn some API design and recognise your 'creative decisions' cost thousands of people countless hours debugging a mess you are deliberately ignoring.

For those struggling with the circular references, you can do something like this:

try {
// your axios request
} catch (error) {
  const { response } = error;
  const { request, ...errorObject } = response; // take everything but 'request'
  res.status(response.status);
  return res.json(errorObject); // or use 'return res.json(response.data.error);' then you don't need to omit the 'request'
}

For those struggling with the circular references, you can do something like this:

try {
// your axios request
} catch (error) {
  const { response } = error;
  const { request, ...errorObject } = response; // take everything but 'request'
  res.status(response.status);
  return res.json(errorObject); // or use 'return res.json(response.data.error);' then you don't need to omit the 'request'
}

Thanks guy! it's code worked fine for me.

The problem is at "lib/core/enhanceError". Request object is added to the error. It makes sense to add response to the answer since there is only one parameter in promise based APIs (request library returns error as first parameter and response as second). But it makes no sense to add all the request. Code change is very simple https://github.com/geoblink/axios/pull/1/files
I could open pr to the main branch if it seems important (I'm not doing it since the issue is closed)

you can make function wrapper which you will call each time when making requests

const api = async (uri, data) => {
  try {
    const { data: response } = await axios({
      url: domain + uri,
      method: 'POST',
      data,
    });

    return response.data;
  } catch (error) {
    throw error.response.data;
  }
};

You are most likely hitting a timeout then, try checking if 'response' exists in the error

axios.get()
.then(function(done) {
   //fine and can get done.data
})
.catch(function(err) {
  //catch the error, check it has a response object with lodash 
  if(_.has(err, 'response') {
     console.log(error.response.status);  
     console.log(error.response.data);
 } 
 else {
    console.log("Most likely a server timeout or an internet connection error");
    console.log("error response property is undefined")
 }
}); 

This is worked for me. Thank you

using "error.response" does not work, for me. The problem occurs when I disconnected the database server and my web server returned error 500.

Network tab in dev tools

response code: 500
response body:

{
  "error": {
    "statusCode": 500,
    "name": "Error",
    "message": "read ETIMEDOUT",
    "code": "ETIMEDOUT",
    "errno": "ETIMEDOUT",
    "syscall": "read",
    "stack": "Error: read ETIMEDOUT\n    at exports._errnoException (util.js:1050:11)\n    at TCP.onread (net.js:582:26)"
  }
}

chrome console error:

Uncaught (in promise) Error: Request failed with status code 500
    at createError (createError.js:15)
    at settle (settle.js:18)
    at XMLHttpRequest.handleLoad (xhr.js:77)

version

"axios": "^0.15.3"

SAME HERE...

In my experience:

"Modify from console.log(error) to console.log(error.response) in catch."

worked better with console.log(error.response.data) in catch.

axios.interceptors.response.use(null, error => {
return error.response;
});

getClients: async (state) => {
const res = await axios.get(${BASE_API}/clients);
console.log('res',res);
if (res){
state.commit("setClient", res.data);
}
}

Another option

/**
 * Whenever error.message is accessed we want to se the full API error message (JSON) if it's present
 * not just some generic http status code + message
 * see https://github.com/axios/axios/issues/960 for context
 *
 * @param axios
 */
export function extractAPIErrorResponse(axios: AxiosInstance) {
    axios.interceptors.response.use(undefined, function (error: AxiosError) {
        (error as any).originalMessage = error.message;
        Object.defineProperty(error, "message", { get: function () {
            if (!error.response) {
                return (error as any).originalMessage;
            }
            return JSON.stringify(error.response.data);
        }});
        return Promise.reject(error);
    })
}

Try{
Await this.$axios .....
}catch(e)
{
console.log(e)

}

axios.get("https://......") 
     .then( response => {
          return response
}).catch( () => {
         store.dispatch("errorComponentMethod")   // if there's an error, method is dispatched
})
//////////////////////////////////////
actions : {
      errorComponentMethod(){
              router.push("/errorComponent")     // method routes to error component
      }
}

Great thanks ! Helped a lot!

still getting this problem. on chrome debugger the response is correct but axios returns a general "Request failed with status code 403" instead

I'm still having this and I am really confused. I tried to catch it is the comments above - but why exactly does axios return undefined when there is an error?
try{ const res = await axios.get("someurl"); return res; } catch(e) { console.log(e); }
res is undefined even though the server is sending back a response with a message in it for WHY it didn't work. And I can't get to that data... why??

**EDIT: found my bug - nothing wrong for me with axios. See my comment two comments down. In short my interceptors were not passing the error data back through the axios pipeline so I was always getting undefined.

@HoogsterInc Have look at the TypeScript definitions here
you could do something like this

try {
   axios.get(...)
} catch (error) {
   if (error.reponse) {
      // http status 4x, 5xx
   } else {
      // network error like timeout, connection refused etc...
   }
}

Thank you for the response trying to help @konstantinblaesi -- I figured out my issue.

For me I had an interceptor set up to check the user's authentication, which if they become unauthed with send a specific error code. I was not however passing along the error data when the error did not match an unauthed code... sigh... silly bad mistake. So after checking for the unauthenticated error code I made sure to return Promise.reject(error); - That solved my problem and the error data comes in full now.

You can use err.toJSON()

catch((err) => {
    console.log(err.toJSON()); // Return error object
});

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

(set for global)

in the main.js

import axios from 'axios'

var instance = axios.create(
 { validateStatus: function (status) {
    return status < 600; #you can change this with another value
  }
 });

or
(set for particular)

  axios.post('/formulas/create', {
       name: "",
       parts: ""
  }, { validateStatus: function (status) {
          return status < 600; // Reject only if the status code is greater than or equal to 500
        }})
    .then( 
   (response) => { console.log(response) },
   (error) => { console.log(error) }
   );

Axios & catch 500 error response data

const log = console.log;

  updateData(options = {}, flag = false){
    let url = `/opapi/appDownloadGuide/update`;
    let message = '更新成功!';
    let errorMessage = '更新失败!';
    if (flag) {
      message = '添加成功!';
      errorMessage = '添加失败!';
      url = `/opapi/appDownloadGuide/add`;
    }
    axios
    .post(url, options)
    .then(res => {
      // ❓🤔️500 , 在这里拦不住呀?
      log(`res`, res, res.status);
      return res.data;
    })
    .then(json => {
      const {
        code,
        success,
        data,
        errorCode,
        errorHint,
      } = json;
      if(code === 200) {
        this.$message({
          type: 'success',
          message,
        });
        this.init();
      } else{
        this.$message({
          type: 'error',
          message: `${errorMessage}: ${errorHint ? errorHint : ""}`,
        });
      }
    })
    .catch(err => {
      // 👌在这里拦截 error data!
      log(`error.response`, err.response);
      const {
        data,
        status,
        statusText,
      } = err.response;
      this.$message({
        type: "error",
        message: `${statusText}-${status}: ${data || ""}`,
        // message: "不能重复创建",
      });
      console.error(`500 err`, err);
    });
  },

https://stackoverflow.com/questions/38798451/how-to-catch-and-handle-error-response-422-with-redux-axios

I have exactly the same environment. Try this:

axios.post('/formulas/create', {
  name: "",
  parts: ""
})
.then(response => { 
  console.log(response)
})
.catch(error => {
    console.log(error.response)
});

_Modify from console.log(error) to console.log(error.response) in catch_.

You can also use a global interceptor and reject only the error.response. The problem is when the console.log tries to output the error, the string representation is printed, not the object structure, so you do not see the .response property.

Not working for me

@gopal-g that's undefined for me.

@gopal-g yes same undefined im getting.

I'm using Axios 0.19.2. I added @konstantinblaesi 's solution:

Another option

/**
 * Whenever error.message is accessed we want to se the full API error message (JSON) if it's present
 * not just some generic http status code + message
 * see https://github.com/axios/axios/issues/960 for context
 *
 * @param axios
 */
export function extractAPIErrorResponse(axios: AxiosInstance) {
    axios.interceptors.response.use(undefined, function (error: AxiosError) {
        (error as any).originalMessage = error.message;
        Object.defineProperty(error, "message", { get: function () {
            if (!error.response) {
                return (error as any).originalMessage;
            }
            return JSON.stringify(error.response.data);
        }});
        return Promise.reject(error);
    })
}

This worked for me, thanks so much @konstantinblaesi ! I don't understand why Axios's default behavior isn't like this -- the standard behavior is to drop the "message" part of the original error, which I would think is the most important part!

Just to be clear, in my app, my server is returning a 400 error (which should be a response):

% curl -X POST http://my-server/api -d '{"foo": "bar"}'
{"status": 400, "message": "missing param XYZ"}

and without this fix, I get from Axios an error object that contains only name, stack, config (which has the original request), and no "response". But with this fix the error contains the correct message property from the server.

As for why there is no "response" property without this fix, it seems to be related to settle in axios.js around line 1171:

        module.exports = function settle(resolve, reject, response) {
          var validateStatus = response.config.validateStatus;
          if (!validateStatus || validateStatus(response.status)) {
            resolve(response);
          } else {
            reject(createError(
              'Request failed with status code ' + response.status,
              response.config,
              null,
              response.request,
              response
            ));
          }
        };

and you can see it doesn't pass through response.message when creating the error. In addition, in my app I don't see the response in error.response, there's no such property -- I don't understand that. But anyway the above fix works for me.

Im trying to catch validation errors from the server.

Code:

axios.post('/formulas/create', {
       name: "",
       parts: ""
})
.then( 
  (response) => { console.log(response) },
  (error) => { console.log(error) }
);

Console log output

Error: Request failed with status code 422
    at createError (app.js:6765)
    at settle (app.js:29489)
    at XMLHttpRequest.handleLoad (app.js:6600)

Network tab output
{"name":["The name field is required."],"parts":["The parts field is required."]}

I should be seeing an object that contains JSON form validation as that is the response in my network tab, i seem to get the JS catch output?

Also tried the following:

axios.post('/formulas/create', {
  name: "",
  parts: ""
})
.then(response => { 
  console.log(response)
})
.catch(error => {
    console.log(error)
});

Same result

More people seem to have the same problem using the same enviroment as me here.
https://laracasts.com/discuss/channels/vue/issues-with-axios-catch-method

  • Axios version: ^0.16.2
  • VueJS 2.3.4
  • Vue-template-compiler 2.3.4
  • Laravel-mix
  • Environment: node v6.4.0, chrome 58, Mac OSX 10.12.4

axios.post('/formulas/create', {
name: "",
parts: ""
})
.then(
(response) => { console.log(response) },
).catch(err => consol.log(err.response.data)});

error.response is an object , it will output [object,object] in console log.
you have to use error.reposne.data to access the error message.
refer : https://itnext.io/javascript-error-handling-from-express-js-to-react-810deb5e5e28

@chandukasm yes but in my case I do _not_ have an error.response -- it is undefined, even though the request was sent and the response received by express. Also see my comment above; the message is ignored (replaced by a generic message) even when a response exists.

error.response is an object , it will output [object,object] in console log.
you have to use error.reposne.data to access the error message.
refer : https://itnext.io/javascript-error-handling-from-express-js-to-react-810deb5e5e28

if you see [object,object] on console.log then just do JSON.stringify(error.response) to see the actual error.

There is no error.response object.

return this.$axios
  .post(postUrl, payload, { responseType: 'json' })
  .then(
    (response) => {
      this.message = `RESP: ${JSON.stringify(response)}`;
    },
    (reason) => {
      this.message = `REAS: ${JSON.stringify(reason)}`;
    }
  )
  .catch((err) => {
    this.message = `CATCH: ${JSON.stringify(err)}`;
  });

payload contains a bad value on purpose to trigger HTTP 422, which in Postman works as expected and the server (LB4) gives back complete error in JSON format explaining where the input data was wrong, but in axios, the error.response object is undefined.

Was this page helpful?
0 / 5 - 0 ratings