'How to catch and handle error response 422 with Redux/Axios?
I have an action making a POST
request to the server in order to update a user's password, but I'm unable to handle the error in the chained catch block.
return axios({
method: 'post',
data: {
password: currentPassword,
new_password: newPassword
},
url: `path/to/endpoint`
})
.then(response => {
dispatch(PasswordUpdateSuccess(response))
})
.catch(error => {
console.log('ERROR', error)
switch (error.type) {
case 'password_invalid':
dispatch(PasswordUpdateFailure('Incorrect current password'))
break
case 'invalid_attributes':
dispatch(PasswordUpdateFailure('Fields must not be blank'))
break
}
})
When I log the error this is what I see:
When I check the network tab I can see the response body, but for some reason I can't access the values!
Have I unknowingly made a mistake somewhere? Because I'm handling other errors from different request fine, but can't seem to work this one out.
Solution 1:[1]
Axios is probably parsing the response. I access the error like this in my code:
axios({
method: 'post',
responseType: 'json',
url: `${SERVER_URL}/token`,
data: {
idToken,
userEmail
}
})
.then(response => {
dispatch(something(response));
})
.catch(error => {
dispatch({ type: AUTH_FAILED });
dispatch({ type: ERROR, payload: error.data.error.message });
});
From the docs:
The response for a request contains the following information.
{
// `data` is the response that was provided by the server
data: {},
// `status` is the HTTP status code from the server response
status: 200,
// `statusText` is the HTTP status message from the server response
statusText: 'OK',
// `headers` the headers that the server responded with
headers: {},
// `config` is the config that was provided to `axios` for the request
config: {}
}
So the catch(error => )
is actually just catch(response => )
EDIT:
I still dont understand why logging the error returns that stack message. I tried logging it like this. And then you can actually see that it is an object.
console.log('errorType', typeof error);
console.log('error', Object.assign({}, error));
EDIT2:
After some more looking around this is what you are trying to print. Which is a Javascipt error object. Axios then enhances this error with the config, code and reponse like this.
console.log('error', error);
console.log('errorType', typeof error);
console.log('error', Object.assign({}, error));
console.log('getOwnPropertyNames', Object.getOwnPropertyNames(error));
console.log('stackProperty', Object.getOwnPropertyDescriptor(error, 'stack'));
console.log('messageProperty', Object.getOwnPropertyDescriptor(error, 'message'));
console.log('stackEnumerable', error.propertyIsEnumerable('stack'));
console.log('messageEnumerable', error.propertyIsEnumerable('message'));
Solution 2:[2]
Example
getUserList() {
return axios.get('/users')
.then(response => response.data)
.catch(error => {
if (error.response) {
console.log(error.response);
}
});
}
Check the error object for response, it will include the object you're looking for so you can do error.response.status
Solution 3:[3]
Here is the proper way to handle the error
object:
axios.put(this.apiBaseEndpoint + '/' + id, input)
.then((response) => {
// Success
})
.catch((error) => {
// Error
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
// console.log(error.response.data);
// console.log(error.response.status);
// console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
});
Origin url https://gist.github.com/fgilio/230ccd514e9381fafa51608fcf137253
Solution 4:[4]
axios.post('http://localhost:8000/api/auth/register', {
username : 'test'
}).then(result => {
console.log(result.data)
}).catch(err => {
console.log(err.response.data)
})
add in catch
geting error response ==> err.response.data
Solution 5:[5]
I was also stumped on this for a while. I won't rehash things too much, but I thought it would be helpful to others to add my 2 cents.
The error
in the code above is of type Error
. What happens is the toString method is called on the error object because you are trying to print something to the console. This is implicit, a result of writing to the console. If you look at the code of toString on the error object.
Error.prototype.toString = function() {
'use strict';
var obj = Object(this);
if (obj !== this) {
throw new TypeError();
}
var name = this.name;
name = (name === undefined) ? 'Error' : String(name);
var msg = this.message;
msg = (msg === undefined) ? '' : String(msg);
if (name === '') {
return msg;
}
if (msg === '') {
return name;
}
return name + ': ' + msg;
};
So you can see above it uses the internals to build up the string to output to the console.
There are great docs on this on mozilla.
Solution 6:[6]
You can use inline if else statement like so:
.catch(error => {
dispatch({
type: authActions.AUTH_PROCESS_ERROR,
error: error.response ? error.response.data.code.toString() : 'Something went wrong, please try again.'
});
});
Solution 7:[7]
The only thing what helped me was the following:
axios.put('/api/settings', settings, {
validateStatus: status => status >= 200 && status < 300 || status === 422
})
Solution 8:[8]
I recommend handling errors via Axios interceptors, individually for each case scenario:
// interceptor to catch errors
const errorInterceptor = (error) => {
// check if it's a server error
if (!error.response) {
console.log('? API | Network/Server error')
return Promise.reject(error)
}
// all the error responses
switch (error.response.status) {
case 400:
console.error(error.response.status, error.message)
console.log('? API | Nothing to display', 'Data Not Found')
break
case 401: // authentication error, logout the user
console.log('? API | Please login again', 'Session Expired')
localStorage.removeItem('user')
break
case 403:
console.error(error.response.status, error.message)
console.log('? API | Access denied', 'Data Not Found')
break
case 404:
console.error(error.response.status, error.message)
console.log('? API | Dataset not found', 'Data Not Found')
break
case 422:
console.error(error.response.status, error.message, error.response.data.detail)
console.log('? API | Validation error', 'Unprocessable Content')
break
default:
console.error(error.response.status, error.message)
}
return Promise.reject(error)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Steve |
Solution 3 | Supervision |
Solution 4 | Afdal Mtk |
Solution 5 | Ryan-Neal Mes |
Solution 6 | Anthony Artemiev |
Solution 7 | chrislow |
Solution 8 | Simon Klimek |