异常处理
异常来自哪里?
- server端数据预获取异常:数据异常,接口异常
- server端 renderer.renderToString 异常
处理方式
1. server 端获取数据异常,让页面继续渲染,在页面加入标志,让client端重新获取数据,代码如下:
entry-server.js服务端部分
// entry-server.js服务端部分
Promise.all(matcheds.map(Component => {
......
}))
.then(() => {
.....
}).catch(err => {
// 交给服务端重定向
if (err.status === 401) {
reject(err)
}
//增加服务端预渲染错误标识,前端拿到标志后重新渲染
context.state = Object.assign(store.state, { serverError: true })
//最后,将服务端vue实例正常返回,避免抛500
resolve(app)
})
entry-client.js客户端部分:
//entry-client.js
......
router.onReady((currentRoute) => {
// node报错时前端路由重渲染(非401状态, 401已经在服务端重定向)
function feCompatibleRende(route) {
let matched = router.getMatchedComponents(route)
console.log('客户端重新AJAX')
Promise.all(matched.map(c => {
if (c.asyncData) {
return c.asyncData({ store, router, route })
}
}))
}
if (window.__INITIAL_STATE__.serverError) {
feCompatibleRende(currentRoute)
}
......
})
2. server 页面渲染过程的异常,出现的问题概率较小,服务端重定向到指定的错误页面
app.use(async (ctx, next) => {
......
try {
status = 200
html = await renderData(ctx, renderer)
} catch (e) {
if (e.status === 404) {
status = 404
return ctx.redirect('/404')
} else if (e.status === 401) {
status = 401
return ctx.redirect('/login')
} else {
status = 500
return ctx.redirect('/500')
}
}
......
})