Axios - Prevent .then() from executing on http errors - javascript

My problem:
I have set up an interceptor to catch error codes in HTTP responses.
When the JWT expires, I have a code 401 coming back from the server. Here's my interceptor:
this.axios.interceptors.response.use(undefined, (error) => {
if (error.response.status === 401) {
this.$store.dispatch('auth/logout').then(() => {
this.$router.push({name: 'login'})
return Promise.reject(error)
})
}
})
My interceptor works fine, except the request that is being intercepted still resolves into the .then() part.
this.axios.get('/texts').then(function(){
// This is still being executed and generates javascript errors because the response doesn't contain the right data
})
From the axios documentation, I found out you can prevent this by calling
this.axios.get('/texts').then(function(){
// only on success
}).catch(function(){
// only on errors
}).then(function(){
// always executed
})
But this is pretty verbose and I don't want to do this on every request that my app makes.
My question is:
How do I prevent axios from executing the .then() callback when I have an error. Is it something I can do in the interceptor? Like event.stopPropagation() or something like that?

You can prevent the Axios Error by using the below set of code
this.axios.interceptors.response.use(undefined, (error) => {
if (error.response.status === 401) {
this.$store.dispatch('auth/logout').then(() => {
this.$router.push({name: 'login'})
return new Promise(() => { });
})
} else {
return Promise.reject(error)
}
})

Throw an exception from catch block to prevent 'then' block
this.axios.get('/texts').then(function(){
// only on success
}).catch(function(e){
// only on errors
throw e;
}).then(function(){
// Will not executed if there is an error but yes on success
})

Did you try catch in the end of the chain? You will get following
this.axios.get('/texts').then(function(){
// only on success
}).then(function(){
// only on success in previous then
}).catch(function(){
// executes on every error from `get` and from two previous `then`
})

Related

Express.js sending response in promise .catch() error

I have a function that looks like this:
function x(req, res, next){
await doSomething().catch(error =>{
return res.send('error here'})
}
await doSomethingElse().catch(error =>{console.log(error)})
return res.send('success');
}
When doSomething() returns an error, I get "Cannot set headers after they are sent to the client", which I understand, but why doesn't the script terminate when I call the first res.send?
My guess is that it's similar to a callback in that the returned value is ignored, so it sends the response, but ignores the fact that the script should end there.
How can I fix this problem?
It gets very complicated to control flow when you are mixing .catch() and await. I would strongly suggest using only one model at a time. With await, you can do this:
async function x(req, res, next) {
try {
await doSomething();
await doSomethingElse();
res.send('success');
} catch(e) {
console.log(e);
res.send('error here'})
}
}
why doesn't the script terminate when I call the first res.send?
Because the return in that statement just returns back from the .catch() handler not from your main function and since you've done a .catch() and not thrown inside that catch handler or returned a rejected promise from the handler, then the parent promise because resolved and execution after the await continues just fine which then causes you to run into the second res.send() which causes the warning about headers already sent.
if you want to use .then() .catch() just try:
function x(req, res, next) {
doSomething()
.catch((error) => {
return res.send("error here");
})
.then(() => {
doSomethingElse()
.catch((error) => {
console.log(error);
})
.then(() => {
return res.send("success");
});
});
}

Axios.catch does not catch network/console errors [duplicate]

This question already has answers here:
Suppress Chrome 'Failed to load resource' messages in console
(3 answers)
Closed 3 years ago.
I am using React with axios and redux-promise. Axios does not appear to catch the 404 error, as below.
This is the code.
const url = FIVE_DAY_FORECAST_URL.replace("{0}", city);
axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
return Promise.reject(error);
});
try{
const request = axios.get(`${url}`).then(e => {
debugger; }).catch(
e => {
debugger;
return "ERROR"; // THIS FIRES, BUT DOES NOT STOP THE CONSOLE ERROR
});
debugger;
return {
type: FETCH_FIVE_DAY_FORECAST,
payload: request
};
} catch {
debugger;
console.log("Error!"); // DOES NOT HELP AS THE 404 IS NOT A JAVASCRIPT ERROR, IT'S A VALID SERVER RESPONSE
}
}
I am using a number of techniques to tr to catch the console error:
.then() ==> the code runs through this block, but the error has already happened, and has been written to the console!
.catch() ==> the code runs through this block if the interceptors are not configured i.e. comment out axios.interceptors.response.use... .
try...catch ==> no effect (does not catch the network response as this is not really a javascript error!)
When using try...catch with axios you explicitly have to state the error response like so
catch(error) {
console.log('[error]', error.response);
// use the error.response object for some logic here if you'd like
}
Otherwise it just returns the string value.
With that response object you can then utilize some logic to do something based on the particular error. More info can be found here https://github.com/axios/axios/issues/960
I hope this helps.
You are trying to catch the Promise.reject and wrapping it in a try...catch. Only one of this will work.
You can either catch a promise rejection or wrap the promise in a try...catch and throw a new error on promise rejection and catch it in catch block.
Try this code
const url = FIVE_DAY_FORECAST_URL.replace("{0}", city);
axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
return Promise.reject(error);
});
try {
const request = axios.get(`${url}`)
.then(
response => {
debugger;
})
.catch(
e => {
debugger;
throw e // throw the error and catch it
});
debugger;
return {
type: FETCH_FIVE_DAY_FORECAST,
payload: request
};
} catch {
debugger;
// Now you can catch the error in catch block
console.log("Error!");
}
// or you can't write async/await code
// make the the function is marked as `async`
try {
const response = await axios.get(`${url}`)
return {
type: FETCH_FIVE_DAY_FORECAST,
payload: response
};
} catch (e) {
console.error("Error happened during fetch");
console.error(e);
}

Firebase Promise chain terminate in catch block

I need to exit http function if first catch block is reached.
I'm doing following
.then() <- start work related with database
.then()
.then()
.catch(error => { <- Here I want to catch errors with firebase database and exit function.
console.log(error)
response.status(500).send(error)
})
.then() <- Here I want to send FCM message if there was no database errors
.catch(error => {
console.log(error)
response.status(200).send("Success") <- Main work with database was finished. I still want to send http 200 and don't care about FCM errors.
})
.then(() => {
response.status(200).send("Success")
}) <-This catch block should be fired if there was an issue with FCM
Problem is that function continue to run after first catch block. How to stop this chain properly in first catch block? Thanks
Something like this should work, using a combination a propagated values and a top-level sentinel:
let bail = false
doWork()
.then(result => {
console.log(result)
return true // indicate success
})
.catch(error => {
console.error(error)
return false // indicate error
})
.then(isPriorSuccessful => {
if (!isPriorSuccessful) {
bail = true
return null
}
else {
// do more stuff here, return a promise
return doMoreWork()
}
})
.catch(error => {
console.error(error)
})
.then(() => {
if (bail) {
res.status(500).send("NOT OK")
return
}
console.log("Just before the end")
res.send("OK")
})

Error Handling in HTTP Ajax Call using $fetch Javascript

I tried to handle the Network related issues in HTTP ajax call. So, I temporarily stopped the respective API's service in IIS and I tried to call the shut downed API - http://localhost:1000/GetData.
fetch("http://localhost:1000/GetData")
.then(handleErrors)
.then(function(response) {
return response.Json();
}).catch(function(error) {
console.log(error);
});
I tried the following code too
fetch("http://localhost:1000/GetData")
.then(response => {
if(response) {
if (response.status === 200) {
alert('Super');
return response.json();
} else {
alert('Hai');
return '';
}
} else {
alert('Oooops');
return '';
}
})
.catch(function(error) {
console.log(error);
});
But its failing and directly hitting the catch block without triggering any alert and its throwing an error. Moreover the response.json(); is in Success block, I don't know how its executed.
TypeError: response.json is not a function
Stack trace:
onFetchError/<#http://192.168.4.159:3000/app.0df2d27323cbbeada2cd.js:9946:13
Kindly assist me how to check the Status code and how to handle the Network error (i.e., Network Unavailable 404, etc.,)
Referred website: https://www.tjvantoll.com/2015/09/13/fetch-and-errors/
Based on this issue on Github, you can try to identify error types in catch block instead. So, something like this may work for your case:
fetch("http://localhost:1000/GetData")
.then(response => {
alert("Super");
return response.json();
})
.catch(err => {
const errStatus = err.response ? err.response.status : 500;
if (errStatus === 404){
// do something
} else {
// do another thing
}
});

Detecting fetch TypeErrors in promise chain

Currently, I'm using fetch with redux-thunk to read code from an API -
my code reads like this:
export function getUsers() {
return (dispatch) => {
// I have some helper code that automatically resolves the json promise
return fetch(`/users`)
.then((resp, json) => {
if (resp.status === 200) {
dispatch(getUsersSuccess(json));
} else {
dispatch(getUsersFail(json));
}
}).catch((err) => {
// network error
dispatch(getUsersFail(err));
});
};
}
The problem here is the catch method, as it will catch any error thrown in the then block. This commonly means that if some React component's render function fails with a programmer error, that error gets swallowed up back into dispatch(getUsersFail(err)).
Ideally, I'd like to detect if err is a fetch error (and dispatch my own action), otherwise throw. However, fetch throws a generic TypeError. How can I reliably detect that the error caught was one thrown by fetch?
Don't use .catch() but install the error handler directly on the fetch promise, as the second - onreject - argument to .then():
return fetch(`/users`)
.then(([resp, json]) => {
if (resp.status === 200) {
dispatch(getUsersSuccess(json));
} else {
dispatch(getUsersFail(json));
}
}, (err) => {
// network error
dispatch(getUsersFail(err));
});
Check out the difference between .then(…).catch(…) and .then(…, …) for details.
Btw, I'd recommend to write
return fetch(`/users`)
.then(([resp, json]) => resp.status === 200 ? getUsersSuccess(json) : getUsersFail(json)
, getUsersFail)
.then(dispatch);

Categories