說明
- 能夠熟練的掌握錯誤的拋出,可以在一定程度上提高代碼的開發效率和可讀性
構造錯誤
- 本栗采用調用一個不存在的函數來拋出錯誤
const Koa = require('koa');
const app = new Koa();// 響應時間輸出中間件
app.use(async (ctx, next) => {await next();// 獲取響應頭,印證執行順序const rt = ctx.response.get('X-Response-Time');console.log(`輸出倒計時: ${ctx.method} ${ctx.url} - ${rt}`);
});// 響應時間統計中間件
app.use(async (ctx, next) => {const start = Date.now();console.log('開始計時');await next();const ms = Date.now() - start;ctx.set('X-Response-Time', `${ms}ms`);console.log('結束計時');
})// 響應
app.use(async ctx =>{await sleep(250);ctx.status = 200;ctx.type = 'html';ctx.body = `<h1>Hello Koa</h1>
})
- 注: 函數的執行順序:
- 根據洋蔥模型: 首先執行
const start = Date.now()
console.log('開始計時')
;- 遇到
await next()
跳到下一個中間件,并將await next()
后面的代碼入一個函數調用棧 - 執行
await sleep(250)
- 由于sleep函數未定義,于是拋出錯誤
- 注: 部分api說明:
const rt = ctx.response.get('X-Response-Time')
: 獲取請求頭部中’X-Response-Time’的值ctx.set('X-Response-Time', '${ms}ms')
: 返回頭部’X-Response-Time’添加值
koa級別拋出錯誤,并獲取處理錯誤
- 拋出錯誤不進行處理
- 將該中間件放在倒數第二個中間件的位置.
// 錯誤處理
app.use(async (ctx, next) => {try {await next();} catch (error) {ctx.status = error.statusCode || error.status || 500;ctx.body = error.message;// 觸發應用層級的錯誤事件ctx.app.emit('error', error, ctx);console.log("中間件捕捉:", error.message);}
})
- 說明:
try{ await next() }
: 嘗試運行下一個中間件,如果遇到錯誤則運行catch塊中的代碼ctx.body = error.message
: 用戶級別的拋出錯誤,用于再瀏覽器中提醒用戶錯誤的信息ctx.app.emit('error', error, ctx)
: koa框架應用層級的錯誤,錯誤的標識為’error’,可以通過app.on('error')
來進行處理.由于此處沒有app.on('error')
,因此會默認的執行以下語句
// 其實不存在
app.on('error', err=>{console.error(err);
})
- 使用
app.on('error', err=>{})
處理
// 拋出node層級的錯誤,
// 向上層拋出錯誤
app.on('error', err=>{throw err;
})
- 注: 后臺直接掛掉.