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