2.4.2
https://gist.github.com/sagarkbhatt/c717f358e568dfc3a65826e0369cf224
Any error inside axios request method will simply ignore by Vue errorHandler
Error should be catch by vue errorHandler
Error is not caught by vue errorHandler
Vue cannot capture errors that are thrown asynchronously, similar to how try... catch won't catch async errors. It's your responsibility to handle async errors properly, e.g. using Promise.catch
@yyx990803 Ok thanks
@yyx990803 Let's think about this, can we provide such a config that let make all lifecycle hooks can be a promise function that we can catch the asynchronous error?
Just like the code below, the created hook is a async function, it is impossible to catch the error.
But if vue deals with the function just like promise catch, it will catch any async error.
import axios from 'axios';
export default {
data() {
return {}
},
async created() {
await axios.get('/user');
}
}
@Emiya0306 that's an interesting suggestion - will consider this in 2.6!
@yyx990803 @Emiya0306 Hey I made a mixin that wraps all component methods and tracks the status of returned promises. It lets you use this.asyncPending inside components and it intercepts any async errors and passes them to vue errorHandler. It's kinda hacky, but also super useful. What do you think?
import Vue from 'vue'
Vue.config.errorHandler = err => {
console.log('handling error:', err)
}
// mixin tracks component asyncPending state and catch async errors by wrapping methods
Vue.mixin({
data: () => ({
asyncPending: 0,
}),
beforeCreate() {
const methods = this.$options.methods
for (const key of Object.keys(methods || {})) {
const method = methods[key]
if (method._busyTracked) return
const wrappedMethod = function(...args) {
const result = method.apply(this, args)
const isPromise = result && typeof result.then == 'function'
if (!isPromise) return result
return new Promise(async (resolve, reject) => {
this.asyncPending++
try {
resolve(await result)
} catch (error) {
if (!error._handled && Vue.config.errorHandler) {
Vue.config.errorHandler(error)
error._handled = true
}
reject(error)
}
this.asyncPending--
})
}
this.$options.methods[key] = wrappedMethod
wrappedMethod._busyTracked = true
}
},
})
Most helpful comment
@yyx990803 @Emiya0306 Hey I made a mixin that wraps all component methods and tracks the status of returned promises. It lets you use this.asyncPending inside components and it intercepts any async errors and passes them to vue errorHandler. It's kinda hacky, but also super useful. What do you think?