Search code examples
javascriptvue.jserror-handlingvuejs2vuex

VueJS Error handling in VueX store best practices


I'm having some issues with the way im handling errors in Vue. Currently im using a try/catch block in VueX to make some async calls. The catch block handles adding the error to a global toast. this is working very well.

async add({ dispatch }, form) {
  try {
    await firebase.add(form)
    dispatch('getUpdatedList')
  } catch (error) {
    // Use the global error handle to handle the error
    dispatch('error', error)
  }
}, 
error ({ dispatch, commit }, errorMessage) {
  console.log(errorMessage)
  commit('ERROR', errorMessage)      
}
// Add the Errors here
ERROR (state, val) {
  state.errors = [val, ...state.errors]
},

The issue I have is this: When that error is caught in the block, it doesn't allow the errors to propagate to the components, so I can't handle the error in the component the way I would like. For example, if the client submits a form, but somehow that fails, the then block of a promise will still execute. So i can't reset the form, or stop a redirect, or do some UI tidy up on the client.

this.$store
    .dispatch('add', this.data)
    .then(() => {
      //This gets hit no matter what the result
      this.showSuccess = true
    })
    .catch(() => {
      // More UI stuff
      //Can only hit this when rethrowing the error
      this.showLoading = false
      this.showRegisterButton = true
    })

I know that I can get around this by rethrowing the error, but that doesn't seem like the best way forward, as I've always believed that rethrowing an error is bad practice (although here it seems like a decent solution) Is there something simple that im missing?


Solution

  • This should be fine, with just one amendment.

    You can re-throw the error to allow parent to catch using throw error

    async add({ dispatch }, form) {
      try {
        await firebase.add(form)
        dispatch('getUpdatedList')
      } catch (error) {
        // Use the global error handle to handle the error
        dispatch('error', error)
        // throw the handled error for another handler to catch
        throw error
      }
    }