Error and Exception handling in Vue.js applications

The error and exception handling is an important part of the architecture of an application. An application must have a good error and exception handling mechanism. It prevents the application from breaking down. Errors can be logged to a server to identify the causes if it is an application in production. A good error handling mechanism helps in improving the user experience. The most common types of errors and exceptions seen in frontend applications are syntax errors, runtime errors, logical errors and Http errors. There are many ways to solve them.For example syntax errors can be detected at compile time using static type checking(Typescript), run time errors can be reduced by using try catch statements in the right way. Unit/Integration testing will help to avoid logical errors. Promises can be used to handle http errors. There are two ways to handle the errors in Vue.js application: they are using vue.js global configuration and the second way is by using ErrorBoundaries or errorCaptured lifecycle hook. 

Using Vue.js global configuration

Vue.js has a global vu.config object which has all the global configurations for the application. These configurations can be overridden with our own configurations. To handle errors we can assign a handler function to Vue.config.errorHandler. If there are any uncaught exceptions the handler gets called. The below lines of codes shows the registration of the handler function.

import Vue from 'vue';

Vue.config.errorHandler = (err, vm, info) => {
  // err: error trace
  // vm: component in which error occurred
  // info: Vue specific error information such as lifecycle hooks, events etc.
  
  // TODO: Perform any custom logic or log to server

};

There are three parameters in the handler err -for complete error trace, vm; is a Vue component/instance in which error is occurred, info;provides specific error information such as lifecycle hooks, events etc. 


Using ErrorBoundaries or errorCaptured lifecycle hook:

errorCaptured is a new lifecycle hook method. It helps you to deal with component specific error within the component itself. It also introduces error boundaries in application. errorCaptured hook has the same signature as global error handler. 


export default {
  name: "app-user-list",

  created() {
    this.$store.dispatch(actionsTypes.FETCH_USER_DATA);
  },

  errorCaptured(err, vm, info) {
    // err: error trace
    // vm: component in which error occurred
    // info: Vue specific error information such as lifecycle hooks, events etc.
    // TODO: Perform any custom logic or log to server
    // return false to stop the propagation of errors further to parent or global error handler
  }
};

Error boundaries are reusable components. These are responsible for catching the unhandled errors/exceptions within its child components tree. 

<template>

  <div>

    <slot

      v-if="err"

      name="error"

      v-bind:err="err"

      v-bind:vm="vm"

      v-bind:info="info"

    >Something went wrong</slot>

    <slot v-else></slot>

  </div>

</template>


<script>

export default {

  name: "error-boundary",

  props: {

    stopPropagation: Boolean

  },

  data() {

    return {

      err: false,

      vm: null,

      info: null

    };

  },

  errorCaptured(err, vm, info) {

    this.err = err;

    this.vm = vm;

    this.info = info;

    return !this.stopPropagation;

  }

};

</script>


<style lang="scss" scoped>

</style>


<template>

  <div class="user-list">

    <error-boundary>

      <app-user-item/>

    </error-boundary>

  </div>

</template>


In our example if there is any uncaught error/exception within app-user-item component ,

It will be handled by an error-boundary component.