Vue: Vue errorHandler is not working inside axios request methods

Created on 8 Sep 2017  路  5Comments  路  Source: vuejs/vue

Version

2.4.2

Reproduction link

https://gist.github.com/sagarkbhatt/c717f358e568dfc3a65826e0369cf224

Steps to reproduce

Any error inside axios request method will simply ignore by Vue errorHandler

What is expected?

Error should be catch by vue errorHandler

What is actually happening?

Error is not caught by vue errorHandler

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?

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
    }
  },
})

All 5 comments

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
    }
  },
})
Was this page helpful?
0 / 5 - 0 ratings

Related issues

6pm picture 6pm  路  3Comments

loki0609 picture loki0609  路  3Comments

bdedardel picture bdedardel  路  3Comments

gkiely picture gkiely  路  3Comments

aviggngyv picture aviggngyv  路  3Comments