Foreword:
The method of sorting out the error information of vue.
- Original: Handling Errors in Vue.js
- Translator: Fundebug
Encyclopedia of errors
In order to test various exception handling techniques, I deliberately trigger three types of errors.
- The first: refer to a variable that cannot exist:
<div id="app" v-cloak>
Hello, {
{name}}
</div>
No error will be thrown after the above code runs, but there will be [Vue warn]
messages in the console .
You can view the complete code of the example in Codepen .
- The second type: bind a variable to a calculated property, and an exception will be thrown during calculation.
<div id="app" v-cloak>
Hello, {
{name2}}
</div>
<script>
const app = new Vue({
el:'#app',
computed:{
name2() {
return x;
}
}
})
</script>
Running the above code will throw a [Vue warn]
and a regular error in the console , and the web page will be blank.
You can view the complete code of the example in Codepen .
- The third type: execute a method that will throw an exception
<div id="app" v-cloak>
<button @click="doIt">Do It</button>
</div>
<script>
const app = new Vue({
el:'#app',
methods:{
doIt() {
return x;
}
}
})
</script>
This error is also [Vue warn]
reported in the console as usual. The difference from the previous error is that only when you click the button will the function call be triggered and the error will be reported.
You can view the complete code of the example in Codepen .
Before continuing, I want to state that the above three examples do not represent all types of errors. These 3 kinds of errors are more common.
Okay, how do we handle the exception? I am surprised that there is no chapter on exception handling in the Vue documentation .
Yes, there is one in the document, but the introduction is extremely brief.
If a runtime error occurs during component rendering, the error will be passed to the global
Vue.config.errorHandler
configuration function (if set). It is a good idea to use this hook function to cooperate with the error tracking service. For example, Sentry , which provides an official integration for Vue .
PS Domestic BUG monitoring service Fundebug also provides official integration for Vue .
I personally suggest that the official should have a detailed introduction. In general, exception handling in Vue includes the following skills:
- errorHandler
- warnHandler
- renderError
- errorCaptured
- window.onerror (not only for Vue)
Tip 1: errorHandler
The first trick we have to learn is errorHandler . As you may know, this is the most widely used exception handling method in Vue.
Vue.config.errorHandler = function(err, vm, info) {
}
err
Refers to the error object, info
a string unique vm
to Vue , referring to the Vue application itself. Remember that you can have multiple Vue applications on one page. This error handler applies to all applications.
Vue.config.errorHandler = function(err, vm, info) {
console.log(`Error: ${err.toString()}\nInfo: ${info}`);
}
The first type of error does not trigger the errorHandler, it is just a warning.
The second type of error will throw an error and be caught by the errorHandler:
Error: ReferenceError: x is not defined
Info: render
The third error will also be caught:
Error: ReferenceError: x is not defined
Info: v-on handler
Remembering info
the information inside is also very useful.
Tip 2: warnHandler
warnHandler is used to capture Vue warning. Remember that it does not work in a production environment.
Vue.config.warnHandler = function(msg, vm, trace) {
}
msg
And vm
it is easy to understand, trace
on behalf of the component tree. Consider the following example:
Vue.config.warnHandler = function(msg, vm, trace) {
console.log(`Warn: ${msg}\nTrace: ${trace}`);
}
The first error is warnHandler
caught:
Warn: Property or method 'name' is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Trace:
(found in <Root>)
You can view the actual operation of the three examples:
first: example 1
second: example 2
third: example 3
Tip 3: renderError
Unlike the previous two, this technique does not apply to the overall situation and is related to components. And only applies to non-production environments.
Here is a simple example:
const app = new Vue({
el:'#app',
renderError (h, err) {
return h('pre', { style: { color: 'red' }}, err.stack)
}
})
The first example is ineffective, because it is just a warning. The second example will display specific error messages on the web page: sample code
To be honest, I don't think this is much better than looking at the console directly. However, if your QA team or testing is not familiar with the browser console, this is still quite useful.
Tip 4: errorCaptured
errorCaptured is the last technique related to Vue. This technique confuses me, but I still don't understand it. The document describes it like this:
Called when an error from a descendant component is caught. This hook will receive three parameters: the error object, the component instance where the error occurred, and a string containing the source of the error. This hook can be returned
false
to prevent the error from continuing to propagate upward.
Based on some of my analysis, this error Handler can only handle errors of child components in the parent component. As far as I know, we cannot use it directly in the main instance of Vue.
To test, I constructed the following example:
Vue.component('cat', {
template:`
<div><h1>Cat: </h1>
<slot></slot>
</div>`,
props:{
name:{
required:true,
type:String
}
},
errorCaptured(err,vm,info) {
console.log(`cat EC: ${err.toString()}\ninfo: ${info}`);
return false;
}
});
Vue.component('kitten', {
template:'<div><h1>Kitten: {
{ dontexist() }}</h1></div>',
props:{
name:{
required:true,
type:String
}
}
});
Note that the kitten
component code is BUG.
<div id="app" v-cloak>
<cat name="my cat">
<kitten></kitten>
</cat>
</div>
The captured information is as follows:
cat EC: TypeError: dontexist is not a function
info: render
The following is a running example .
errorCaptured
It's a very interesting feature, I think developers who build component libraries should use it. This feature is more like a component-oriented developer rather than a general developer.
Ultimate trick: window.onerror
The last and most important candidate is window.onerror . It is a global exception handling function that can capture all JavaScript exceptions.
window.onerror = function(message, source, line, column, error) {
}
I think the only parameter of the function is source
hard to understand literally, it represents the current URL.
The next thing is more fun. If you define it onerror
but not enable it Vue.config.errorHandler
, there are many exceptions that will not be caught. Vue expects you to define it, otherwise the exception will not be thrown. Does this make sense? I don't understand it very well, I don't think it is necessary, or even a little strange.
If the defined errorHandler
code has a BUG, it will not be onerror
caught when it runs . In the following example, if you will oopsIDidItAgain()
comment, you will find this problem. Only the second button is not bound to Vue, so errors will be caught anyway. Run instance