nodejs中使用throw進行異常處理的操作方法
使用return來返回特定格式的錯誤數(shù)據(jù)
用例子來解釋一下,如下代碼所示:
// 一個校驗數(shù)據(jù)的方法(采用return來返回特定格式數(shù)據(jù)的方式) const validateData = (data) => { if (!data.name) { return { pass: false, message: '名稱不能為空' } } } // 一個提交數(shù)據(jù)的方法,在其中調(diào)用校驗方法 const submit = (data) => { const res = validateData(data); if (!res.pass) { // 提示用戶錯誤信息 alert(res.message); } } submit({ name: '' });
在上面的代碼中,validateData
方法使用return返回特定格式的數(shù)據(jù),在提交數(shù)據(jù)之前調(diào)用validateData
方法校驗數(shù)據(jù),校驗不通過將錯誤信息提示給用戶。
上面這個例子是在前端項目中經(jīng)常會遇到的一種情況,但是在后端項目中,重點并不是提示用戶錯誤信息,而是在接口中以特定格式返回錯誤信息,例如:
// 一個校驗數(shù)據(jù)的方法(采用return來返回特定格式數(shù)據(jù)的方式) const validateData = (data) => { if (!data.name) { return { pass: false, message: '名稱不能為空' } } } // 一個在數(shù)據(jù)庫表中新增一行數(shù)據(jù)的方法,在其中調(diào)用校驗方法,return返回的數(shù)據(jù)將會作為接口的返回數(shù)據(jù) const addRow = (data) => { const res = validateData(data); if (!res.pass) { return { code: -1, message: res.message } } // 數(shù)據(jù)庫中新增數(shù)據(jù) } addRow({ name: '' });
在上面的代碼中,通過兩層return
來返回數(shù)據(jù);在只有兩層時還好維護這樣的代碼,但是當(dāng)后端代碼處理的業(yè)務(wù)非常復(fù)雜,方法調(diào)用層級非常深后就會變得難以維護,因為每一層方法都要判斷下一層的返回然后再處理結(jié)構(gòu)后返回給上一層。那我就在想如何更簡單呢?想到了直接使用throw
來拋出錯誤。
使用 throw 來拋出錯誤
在后端項目代碼中,主要是處理業(yè)務(wù)邏輯然后將結(jié)果通過接口返回,不像前端項目代碼中有一部分業(yè)務(wù)邏輯還有用戶交互。所以完全可以添加一個中間件,處理代碼中拋出的所有錯誤然后封裝后返回給接口調(diào)用方。例如在nodejs項目中:
// app.js文件 import 'express-async-errors'; // 引入這個模塊后能捕獲未被處理的異步報錯并傳遞給錯誤處理中間件 import express from 'express'; import routes from './routes'; const app = express(); // 一次性掛載所有路由 app.use(routes); // 全局錯誤處理中間件,所有未捕獲的報錯都在此處理,業(yè)務(wù)代碼專注于業(yè)務(wù)邏輯即可 app.use((error, req, res, next) => { // 統(tǒng)一處理所有沒有被捕獲的報錯 res.status(200).json({ code: -1, message: error?.message || '服務(wù)器錯誤!', data: null }); }); // routes.js文件 import express from 'express'; const router = express.Router(); // 一個校驗數(shù)據(jù)的方法(采用thorw來拋出錯誤的方式) const validateData = (data) => { if (!data.name) { throw new Error('名稱不能為空'); } } // 一個在數(shù)據(jù)庫表中新增一行數(shù)據(jù)的方法,在其中調(diào)用校驗方法 const addRow = (data) => { // 校驗數(shù)據(jù) validateData(data); // 數(shù)據(jù)庫中新增數(shù)據(jù) } // 定義了一個路徑為 /addRow 的路由,調(diào)用了 addRow 方法 router.get('/addRow', (req, res) => { addRow({ name: '' }); })
這樣,不論是在多深層級的方法中用throw
拋出一個錯誤,只要沒有被捕獲,都能在最外層處理。
為什么要“用throw拋出錯誤然后在全局錯誤處理中間件中處理”這樣去做?
因為在后端業(yè)務(wù)邏輯復(fù)雜的情況下,可能會存在很多層級的代碼調(diào)用,全部使用return來返回特定格式數(shù)據(jù)在編寫和維護時較為復(fù)雜,而使用throw來拋出后統(tǒng)一處理有這些好處:
統(tǒng)一處理錯誤,讓代碼編寫和維護變得更簡單
- 統(tǒng)一處理錯誤:通過
throw
拋出錯誤并在全局錯誤處理中間件中處理,能夠?qū)⑺蓄愋偷腻e誤(如路由處理中的錯誤、數(shù)據(jù)庫操作錯誤、第三方 API 調(diào)用錯誤等)集中到一個地方進行處理;這能夠讓錯誤處理邏輯更加清晰和有條理,避免了錯誤處理零散的分布在各個模塊方法中。 - 編寫維護簡單:在深層級的方法中編寫代碼不用考慮錯誤情況下的數(shù)據(jù)返回,直接拋出錯誤即可;所有的錯誤處理邏輯都在一個地方,后續(xù)有錯誤邏輯的更新只需要修改這一個地方即可,便于維護。
- 統(tǒng)一處理錯誤:通過
增強程序的穩(wěn)定性
- 防止程序崩潰:在某個方法或者模塊中發(fā)生錯誤時,如果沒有處理,可能會導(dǎo)致整個程序崩潰;通過全局錯誤處理中間件來處理所有未被捕獲的錯誤,能夠避免單個錯誤引發(fā)的程序崩潰終止。
一致的用戶體驗
- 統(tǒng)一的錯誤信息數(shù)據(jù)結(jié)構(gòu):在全局錯誤處理中間件中可以統(tǒng)一錯誤信息的數(shù)據(jù)結(jié)構(gòu)后返回給客戶端。這樣客戶端代碼能夠更好的處理錯誤將錯誤展示給用戶。
- 清晰的錯誤提示:針對一些錯誤碼的報錯,可以將其轉(zhuǎn)化為用戶能夠理解的文字提示后返回給客戶端。
以上就是nodejs中使用throw進行異常處理的操作方法的詳細內(nèi)容,更多關(guān)于node throw異常處理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用GruntJS構(gòu)建Web程序之Tasks(任務(wù))篇
任務(wù)(Tasks)是grunt的核心概念,你所做的很多工作比如資源合并(concat)、壓縮(uglify)都是在配置任務(wù)。 每次grunt運行的時候,你指定的一個或多個任務(wù)也在運行,如果你沒有指定任務(wù),那么一個默認名為“default”的任務(wù)將自動運行。2014-06-06Node.js中Bootstrap-table的兩種分頁的實現(xiàn)方法
這篇文章主要介紹了Node.js中Bootstrap-table的兩種分頁的使用方法,需要的朋友可以參考下2017-09-09Nodejs監(jiān)控事件循環(huán)異常示例詳解
這篇文章主要給大家介紹了關(guān)于Nodejs監(jiān)控事件循環(huán)異常的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Nodejs具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09