Reputation: 3760
Here's my chunk of code:
const getToken = async () => {
try {
const token = await axios.post(keys.sessionURL, {
email: keys.verificationEmail,
password: keys.verificationPassword,
});
} catch (err) {
throw new Error('Unable to establish a login session.'); // here I'd like to send the error to the user instead
}
};
So as you can see I'm connecting to external server in order to get a token. And that works. Now, I'd like to catch an error but this time not with 'throw new error' but I'd like to send it to the user, so I'd like to have something like this instead:
res.status(401).send('Unable to get a token');
But because I'm not inside the route handler I cannot use 'res'. How can I send it to the user then?
Thank you!
Upvotes: 59
Views: 120590
Reputation: 1
const getPass = (e) => {
e.preventDefault()
const post = { userName: userName }
axios.post("/", post) //axios.post(keys.sessionURL, {email: keys.verificationEmail,password: keys.verificationPassword,})
.then(res => {
if(!res.ok){
throw Error('Network Error'); //error from axios
}
return res.json();
}).catch(err => {
console.log(err.message) //to display the error to your user just use the useState to define your error
})
}
const getPass = (e) => {
e.preventDefault()
const post = { userName: userName }
axios.post("/", post) //axios.post(keys.sessionURL, {email: keys.verificationEmail,password: keys.verificationPassword,})
.then(res => {
if(!res.ok){
throw Error('Network Error'); //error from axios
}
return res.json();
}).catch(err => {
console.log(err.message) //to display the error to your user just use the useState to define your error
})
}
Upvotes: -1
Reputation: 1272
For axios version-0.19.0 below code worked after hours of struggling with async await.Not sure about other versions though!
catch(error){
console.log(error.response.data.error)
}
Upvotes: 68
Reputation: 10502
Elegant & with TypeScript.
import axios, { AxiosResponse, AxiosError } from "axios";
...
const response: void | AxiosResponse<any, any> = await axios({
headers: {
Authorization: `Bearer ${XYZ}`,
Accept: "application/json",
},
method: "GET",
params: {
...
},
url: "https://api.abcd.com/...",
}).catch((error: AxiosError) => {
if (error instanceof Error) {
console.error(
"Error with fetching ..., details: ",
error
);
}
});
Upvotes: 3
Reputation: 468
Keep the grace of async / await
:
const result = await axios.post('/url', params)
.catch((err) => {
// deal with err, such as toggle loading state, recover click and scroll.
this.loading = false;
// recover the reject state before.
return Promise.reject(err);
});
this.data = result; // not exec when reject
Upvotes: 9
Reputation: 3184
try/catch is not a good solution. It's meant to catch runtime error, not HTTP error coming from axios if error is processed by interceptor and then passed back to caller via return Promise.reject(error);
here is interceptor example
axios.interceptors.response.use(
response => {
//maybe process here
return response;
},
error => {
//do some global magic with error and pass back to caller
return Promise.reject(error);
}
);
Let's start with try/catch example that won't work
for(let i=0; i<5;i++) {
try{
const result = async axios.get(`${/item/{i}}`);
}
catch(error) {
//error undefined here, you would expect an error from pattern like axios.get(...).then(...).catch(real_http_error)
}
}
I found this pattern to work. Let say you want to make calls in a loop to make avoid multiple http call due to async nature of JS.
for(let i=0; i<5;i++) {
const result = async axios.get(`${/item/{i}}`).catch(error) { //chain catch despite async keyword
//now you access http error and you can do something with it
//but calling break; or return; won't break for loop because you are in a callback
}
if(!result) { //due to http error
continute; //keep looping for next call
//or break; to stop processing after 1st error
}
//process response here, result.data...
}
Upvotes: 8
Reputation: 402
In my solution I use:
try{
let responseData = await axios.get(this.apiBookGetBookPages + bookId, headers);
console.log(responseData);
}catch(error){
console.log(Object.keys(error), error.message);
}
If something failed we will get en error like this:
[ 'config', 'request', 'response', 'isAxiosError', 'toJSON' ]
'Request failed with status code 401'
We can also get status code:
...
}catch(error){
if(error.response && error.response.status == 401){
console.log('Token not valid!');
}
}
Upvotes: 9
Reputation: 415
You can keep almost the same function
const getToken = async () => {
try {
const token = await axios.post(keys.sessionURL, {
email: keys.verificationEmail,
password: keys.verificationPassword,
})
} catch (err) {
throw new Error('Unable to get a token.')
}
}
Then from your route handler just catch
the eventual exception
app.get('/endpoint', async (req, res) => {
try {
const token = await getToken()
// Do your stuff with the token
// ...
} catch (err) {
// Error handling here
return res.status(401).send(err.message);
}
})
The default js exception system works well to pass error data through the call stack.
Upvotes: 20
Reputation: 1445
you keep a flag like isAuthError
and if error occurs send it as true and in the main function if the flag isAuthError
is true throw the err and handle in catch otherwise perform your operations. I've added an example below. hope it helps
const getToken = async () => {
try {
const token = await axios.post(keys.sessionURL, {
email: keys.verificationEmail,
password: keys.verificationPassword,
});
return {token, isAuthError: false};
} catch (err) {
// throw new Error('Unable to establish a login session.'); // here I'd like to send the error to the user instead
return {err, isAuthError: true};
}
};
app.post('/login', async (req, res)=>{
try{
// some validations
let data = await getToken();
if( data.isAuthError){
throw data.err;
}
let token = data.token;
//do further required operations
}catch(err){
//handle your error here with whatever status you need
return res.status(500).send(err);
}
})
Upvotes: 6