I have a problem that I can't solve with vue.js
I intercept queries that return an error (axios interceptor), and when it passes through this interceptor, the catch of the axios query is still taken into account.
Except that I wait for an error "error.api". which I don't receive, so it generates a console error.
Here is the code:
axios.interceptors.response.use(null, error => {
let path = '/login';
switch (error.response.status) {
case 401: path = '/login'; break;
case 404: path = '/404'; break;
}
store.commit('logout')
router.push(path);
return Promise.reject(error);
});
this error
2.js:376 Uncaught (in promise) TypeError: Cannot read property 'api' of undefined
And finally, the axios query and the error is generated by the last line (err.api[0])
deleteApi(id) {
this.$store.dispatch('deleteApi', id)
.then((res) => {
this.$toast.success(res.data.success)
this.deleteApiModal(id)
})
.catch(err => this.$toast.error(err.api[0]))
},
I finally found a solution but very dirty, which I find repetitive for not much.
It's on each call axios, to put a condition that checks if "err" exists...
I would have preferred to be able to interact on the interceptor to have managed this in only one place.
If someone has a better solution, I'll take it !
deleteApi(id) {
this.$store.dispatch('deleteApi', id)
.then((res) => {
this.$toast.success(res.data.success)
this.deleteApiModal(id)
})
.catch(err => { if(err) this.$toast.error(err.api[0]) })
},
Related
I have a service.js which has some axios requests. When I post something using this service from view, I can't handle errors, because all errors falls into success chain instead of error.
This line is from service.js
async createIsp(payload) {
return await apiService.post('/isp', payload)
}
And this one is from view:
function saveIsp() {
clicked.value = true
ApiService.createIsp({isp_name: newIsp.value}).then((data) => {
clicked.value = false
//all response falls here... even its error.
//router.push({name: 'isp'})
}).catch(e => console.log(e))
https://stackoverflow.com/a/70542347/3054818
This is the solution. I am using interceptors, and I should throw error.
I'm new to vue. I use interceptors for handling action responses, all easy with successful responses. But I would like to know what are the best practice to handle error responses.
I want to show a toastr with error message from response by default if there's no catch block in the action, but if there is a catch, do only catch function with no toastr shown.
Also, is it ok to handle unauthorized response making a redirect to login page directly in interceptor and what advices can be given about it?
My current interceptor looks like this:
axios.interceptors.response.use(
(response) => {
return response.data.data;
},
(error: AxiosError) => {
const data = error.response?.data;
const code = data?.code;
if (code === ErrorCodes.NEED_EMAIL_CONFIRMATION) {
router.push("email-verification").then();
} else if (code === ErrorCodes.UNAUTHORIZED) {
router.push("sign-in").then();
} else {
if (undefined !== data.error) {
toaster.error(data.error);
} else {
toaster.error(i18n.t("unexpected"));
}
}
return error;
}
);
but I don't like too many responsibilities here and I don't know how to avoid toastr show when the action has a catch function
You can control error toast notification from where you send the request, by sending an extra config.
Using axios:
axios.post('/api-name', data, {
config: {
showToast: true,
},
})
and then on axios intercept:
axios.interceptors.response.use(
response => {...},
error => {
const showTost= error.config.errorToast
if(showToast){
// show toast you can pass custom message too...<3
}
}
If getting response like this-
data: Array(0)
length: 0
How to handling the error and how to show message the no matching data found in vuejs.
First of all, you should either wrap your axios request with try/catch if using async/await, or simply use then..catch methods.
Here's a simple example
axios.get('http://api.com')
.then((response) => {
if (response.data.length === 0) { // Lets check if response contains any items
// Do Your 'no items found' logic here
console.log('No items found')
return
} else { // We have items, handle them here!
// We have some items, lets log them
console.log(response.data)
}
})
.catch((error) => {
// Catch and handle any errors here
console.log(error)
})
In my project, I use RxJS to handle HTTP request. I came into a confusing point about the error handling part as following:
.switchMap((evt: any) => {
return http.getComments(evt.params)
.map(data => ({ loading: false, data }))
.catch(() => {
console.log('debugging here');
return Observable.empty();
});
})
in the above code, inside the switchMap operator, I use the http.getComments function to send request, which is defined by myself as following:
getComments(params) {
return Observable.fromPromise(
this.io.get(path, { params })
);
}
in this function, I use fromPromise operator convert the returned Promise to observable.
The problem is when HTTP request failed, the catch operator inside switchMap can not work, the debugging console can't output. So what's wrong with my code.
Do you really need to catch the error inside the switchMap anyway? You can handle your error in your source if you want.
.switchMap((evt: any) =>
http.getComments(evt.params).map(data => ({ loading: false, data }))
})
.subscribe(console.log, console.error);
Any way, your source code does not look to have any error, maybe your promise is not been rejected when the http fails and is just resolving with an error as a response (this is a guess because I've seen that before)
Your code should work. Here a simplified simulation, where http calls are substituted by a function which raises an error.
import {Observable} from 'rxjs';
function getComments(params) {
return Observable.throw(params);
}
const params = 'abc';
Observable.of(null)
.switchMap(_ => {
return getComments(params)
.map(data => ({ loading: false, data }))
.catch(err => {
console.log('debugging here', err);
return Observable.empty();
});
})
.subscribe(
console.log,
error => console.error('This method is not called since the error is already caught', error),
() => console.log('DONE')
)
I'm getting this error message with the snippet below
Unhandled rejection Error: reply interface called twice
Note that I'm using return for all the reply() interface
Locations
.findOne({
_id: request.params.id,
activationCode: payload.activationCode
}).then((location) => {
if (!location) {
return reply(Boom.notFound('Location not found'))
}
locationObject = location
if (payload.password !== payload.confirmPassword) {
return reply(Boom.badRequest('Password and Confirm Password must match'))
}
if (!payload.terms) {
return reply(Boom.badRequest('Must agree to Terms & Conditions'))
}
return newPaymentMethod.save()
}).then((paymentMethod) => {
.....
return user.save() // user is defined at .....
}).then(() => {
return reply({ token: helpers.createJwt(userObject) })
}).catch((err) => {
return reply(Boom.wrap(err))
})
Any help would be appreciated.
Looks like you get caught into this due to the incorrect use of promises. I guess you’re executing your snippet within a route handler where you’ve access to reply.
As you’re returning your responses within the promise chain, you both return the value to the next .then (promise) and also calling the reply from the outer scope.
I suggest you use a promise reject for errors so that you only need a single reply(Boom.method()) within the promise’s .catch().
Since you chain promises in the end
.then(() => {
return reply({ token: helpers.createJwt(userObject) })
}).catch((err) => {
return reply(Boom.wrap(err))
})
you might call reply twice if any of if conditions is true.
Easy solution would be to throw error in if condition is true - since there is already a Boom.wrap in catch block.