Vue.js Error handling Typescript
▌Introduction
We are
going to learn how to do global error handling in Vue.js, including of:
Type:
(err: Error, vm: Component, info: string)
The
global error handler for uncaught errors during component render function and
watchers.
Notice
that it can also catch the error from asynchronous function, but the call stacks
must be all async.
Type:
(err: Error, vm: Component, info: string) => ?boolean
This hook (method) is put on a parent component and will be
called when an error from sub-component(s) is captured.
We can return false on this hook to stop propagating
further.
The sample codes in based on Typescript.
However, the concept and codes can be applied to Javascript.
|
▋Related articles
2. [Vue] Error Handling
▌Environment
▋vue.js 2.6.6
▋Vue CLI 3.5.1
▋typescript 3.2.1
▌Implement
▋Global
error handler
Lets create a custom error handler and assign it to Vue.config.errorHandler
later.
▋error-handler.ts
import toastr from 'toastr';
/**
*
Format component's name
*
* @param {*} vm
{Compoent}
*/
const formatComponentName = (vm: any) => {
if (vm.$root ===
vm) {
return 'root';
}
const name = vm._isVue
?
(vm.$options
&& vm.$options.name) ||
(vm.$options
&& vm.$options._componentTag)
:
vm.name;
const errComponent = name ? 'Component
"' + name + '"' : 'unknown
component';
const errFile =
vm._isVue
&& vm.$options
&& vm.$options.__file ? vm.$options
&& vm.$options.__file : '';
return `${errComponent} at ${errFile}`;
};
/**
*
Global error handler
*
* @param {*} err
{Error message}
* @param {*} vm
{Compoent}
* @param {*} info
{Error information}
*/
const errorHandler = (err: any, vm: any, info: any) => {
//
err: error trace
//
vm: component in which error occured
//
info: Vue specific error information such as lifecycle hooks, events etc
// Do
something here…
//
For example, use toastr to show the error
toastrCustom.error(err);
};
export { errorHandler };
Then we
can configure the global error handler,
▋main.ts (for Vue CLI)
import { errorHandler as customErrorHandler } from '@/modules/error-handler';
/* Global Vue config */
Vue.config.errorHandler = customErrorHandler;
It’s done!
Here are some captured samples.
▋Normal error
const err = 'Shit
happens';
throw err;
Result:
▋Error from Async function
When using async-await on function, make sure the
call stacks are all async-await.
If you call an async function in another
non-async function, the error from the async function will NOT BE CAPTURED by
the global error handler!
async mounted() {
await new Promise((resolve, reject) => {
reject('Shit happens in Asyc
function')
});
},
▋errorCaptured
hook
We can put an errorCaptured hook on a parent
component to capture the error(s) from sub-components.
Take the following routes for example, the Main
component is supposed to has the errorCaptured hook.
const routes = [
{
name: 'main',
component: Main,
children: [
{ path: 'home', name: 'home', component: Home },
{ path: 'about', name: 'about', component: About }
],
},
];
▋Main.vue
<script lang="ts">
export default Vue.extend({
name: 'Main',
data() {
return {
};
},
errorCaptured (err: any, vm: any, info: any) {
// Do
something here…
toastr.error(err);
}
});
</script>
Now we can capture error(s) from sub-component. For
example, we get an error when mounting the sub-component, and results in:
Wait a minute! Why we got 2 error messages on one
error?
Because the errorCaptured hook in default propagated
the error on upper level, so the global error handler also captured the error.
To stop the errorCaptured hook propagate further,
return false inside it.
errorCaptured (err: any, vm: any, info: any) {
toastrCustom.error(err);
return false;
},
▋More..
Though
we can capture most errors, however it’s hard and costly trying to catch all
errors on client-side.
It
is recommend to use Sentry for advanced usage.
▌Reference
沒有留言:
張貼留言