简介
NuxtJS中的错误从产生到流经到最后的展示,有着一套既定的规则。本文通过对NuxtJS框架中错误流转的介绍,帮助读者准确的定位错误,并正确处理应用中的错误。
通过本文,你可以:
- 了解NuxtJS错误的分类与流转机制
- 了解不同错误的捕获方式与处理技巧
- 了解NuxtJS错误页的展示原理,以及自定义错误页。
错误来源
NuxtJS框架中的错误来源有以下三种:
- 事件处理函数
- asyncData方法
- 组件模版渲染
错误处理
抛出的错误可以在以下四个位置进行捕获:
- errorCapture
- Vue.js errorHandler
- onunhandledrejection
- render:errorMiddleware
错误展示
若不进行错误的处理,错误将最终被展示出来,有以下三种形式:
- 浏览器Console
- NuxtJS错误页
- 静态错误页
错误来源
错误产生及传播可由下面的两张图表示:
【图1】事件处理函数中抛出的错误仅会出现在客户端(client-side)
【图2】asyncData方法中以及组件模版渲染中抛出的错误既可能出现在客户端(client-side)也可能出现在服务端(server-side)
错误处理
errorCapture
errorCapture是Vue组件的一个生命周期Hook,在NuxtJS中,同样可以为Layout组件添加。在Layout组件中设置errorCapture,可以让你全局捕获和处理这些错误:
- 事件处理函数(client-side)中的同步错误
- 组件模版渲染(client-side & server-side)中的错误
DEMO in 默认Layout – NuxtJS
/**
* @file layouts/default.vue
*/
import Vue from 'vue'
import Component from 'vue-class-component'
@Component({
errorCaptured(err, vm, info) {
if (info === 'render') {
console.log('这是一个组件渲染的错误')
} else {
console.log('这是一个事件处理的错误')
}
console.log('[errorCaptured 错误处理]: ', err, vm, info)
// 阻止错误继续向外传播
return false
},
})
export default class Layout extends Vue {
...
}
复制代码
errorHandler
errorHandler 是Vue全局配置的一项,你可以使用它去捕获和处理这些错误:
- 事件处理函数(client-side)中的同步错误且未被errorCapture处理掉
- 组件模版渲染(client-side)的错误且未被errorCapture处理掉
DEMO in plugins – NuxtJS
/**
* @file plugins/monitor.client.js
*/
import Vue from 'vue'
export default function (ctx) {
Vue.config.errorHandler = (error, vm, info) => {
console.log('[errorHandler 错误处理]: ', err, vm, info)
}
}
复制代码
onunhandledrejection
onunhandledrejection是浏览器事件,可以捕获异步的代码错误,包括:
- 事件处理函数(client-side)中的异步错误
- asyncData(server-side)中的错误
DEMO in plugins – NuxtJS
/**
* @file plugins/monitor.client.js
*/
export default function (ctx) {
window.onunhandledrejection = (event) => {
console.log('[onunhandledrejection 错误处理]: ', event, event.reason)
}
}
复制代码
render:errorMiddleware
render:errorMiddleware是NuxtJS内部向外暴露的一个hook,他本质上是添加一个connect的错误中间件,而connect是NuxtJS底层用于实现HTTP Server的框架。
值得关注的是,在render:errorMiddleware
中你并不能阻止错误继续传播下去,也就是说你不能阻止 静态错误页 的展示。如果想避免静态错误页的展示,你需要在asyncData
中捕获并处理掉这些错误。
DEMO in The hooks Property – NuxtJS
/**
* @file hooks/render.js
*/
export default (nuxtConfig) => ({
errorMiddleware(app) {
app.use((error, _req, _res, next) => {
if (error) {
console.log('[errorMiddleware 错误处理]: ', error)
}
// 将传递给后面的错误中间件继续处理
next(error)
})
},
})
复制代码
错误页面
当错误没有被正常处理掉,会最终展示在前端界面上,共有三种形式。
浏览器Console
事件处理函数中的错误会仅会展示到浏览器的Console(控制台)上,不会导致页面的崩溃(即我们常说的白屏)。
NuxtJS错误页
客户端的asyncData错误和模版渲染错误会展示NuxtJS错误页。使用 context.error方法也会导向该页面。
你可以通过添加layouts/error.vue
文件来覆盖默认的NuxtJS错误页。
DEMO in layouts/error.vue
/**
* @file layouts/error.vue
*/
@Component({
props: {
error: {
type: Object,
default: () => ({}),
},
},
})
export default class ErrorPage extends Vue {
mounted() {
console.log('[layouts/error 错误展示]: ', error)
}
}
复制代码
静态错误页
服务端的asyncData错误和模版渲染错误会展示静态错误页:
但是在开发环境下,你不会看见如上页面,会改为展示 youch 错误页面:
你可以通过添加app/views/error.html
文件来覆盖默认的静态错误页。
DEMO in app/views/error.html
/**
* @file app/views/error.html
*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>错误页</title>
</head>
<body>
<h1>服务器崩溃了,嘤嘤嘤~</h1>
</body>
</html>
复制代码