今天要來講講錯誤處理的部分,先讓我們來想想在網頁上是如何進行錯誤處理的。只要服務有持續在運行,就一定要假設錯誤是會發生的,包括網路發生問題、資料庫發生問題、流量過載、程式 Bug、雲端服務提供商或串接的其他服務有些問題,都可能造成程式上無法正常運作達到使用者的預期目標。這類無法正常解決的問題,在網頁上可能是用 HTTP Status 500 的方式呈現,在網頁前端則可以刻一個適合風格的錯誤訊息頁面。
在開發環境上,從 React 的開發經驗中我們可以學習到,錯誤可以非常明顯最好,甚至是蓋版的也可以,反正目標是幫助開發人員快速除錯,例如 Create React App 在開發時是這樣處理錯誤:
在實際上線環境則不會這樣顯示。
(注意:今天請務必使用最新版本的 bottender,較舊的版本可能會沒有這個功能)
那在機器人上錯誤處理應該是怎麼樣子的呢?
開發環境,我們目標應該也是要讓錯誤能輕易發現。
在實際上線環境則不一定,有時候最好的錯誤處理可能是讓機器直接不講話,或甚至轉給真人客服處理,但有時候可能會想告知使用者現在有問題請稍後再試。
先來看看目前遇到錯誤的預設處理方式是怎樣,所以我把程式碼改一下,改成會直接拋出錯誤:
module.exports = async function App(context) {
throw new Error('Boom!');
};
執行起來會是這樣:
預設的狀況會是只在 Console 印出錯誤,在體驗上就是不讀不回。
你可以在你的專案下新增 _error.js
檔案來決定要怎麼針對錯誤回應這個訊息給使用者。
module.exports = async function HandleError(context, { error }) {
if (process.env.NODE_ENV === 'production') {
await context.sendText('對不起現在服務有點異常,請稍後再試~');
} else {
await context.sendText(error.stack);
}
};
在 production
下:
在 develop
下:
(注意:這邊是如果送的出去真的會送給使用者,而不只是顯示在 Console 而已喔)
就像前面所說的,可以客製化的部分很多,你可以讓他遇到錯誤就轉真人客服、或是標示已讀等等,這也關乎各平台的功能限制。
特別是寫了這樣一篇文章,更能感覺到錯誤處理還有很多能優化、改善的部分,未來可能會直接有個更好用的預設錯誤處理方式,讓開發時 Debug 都能再更方便一些。