這個(gè)項(xiàng)目是集成了第三方NeteaseCloudMusicApi項(xiàng)目的接口代碼,我沒有直接使用它的接口,因?yàn)樾枰倥芤粋€(gè)npm run開個(gè)端口,感覺很麻煩。
所以下定決心,使用拆分代碼的方式,硬生生將這個(gè)api項(xiàng)目的部分api接口代碼集成到了我自己的項(xiàng)目。當(dāng)然前提是必須能看懂它的代碼,然后才能做拆分,否則你根本無從下手
最后終于都搞定了,這個(gè)過程很復(fù)雜,把它的api代碼拆分到了我自己的項(xiàng)目中。
但是有個(gè)問題,有時(shí)候請求歌曲的時(shí)候會(huì)報(bào)404錯(cuò)誤
?但是這個(gè)404錯(cuò)誤報(bào)的明顯不正確,因?yàn)槲乙呀?jīng)在代碼里打了埋點(diǎn):
?上面證明:這個(gè)接口請求實(shí)際已經(jīng)匹配到路由了,所以絕不應(yīng)該是404錯(cuò)誤!
然后排查代碼發(fā)現(xiàn)這個(gè)第三方api的錯(cuò)誤處理代碼居然寫的是404!
這就不對(duì)了,肯定起碼應(yīng)該是個(gè)500,但是這還不夠,起碼得知道是什么錯(cuò)誤,
所以,把它的msg的值寫成捕獲到的err
?本以為這樣處理就應(yīng)該能看到具體的異常信息了,但是實(shí)際返回結(jié)果卻還是空對(duì)象:
?問題變得棘手了,異常明明捕獲到了啊,可是為什么打印不出來呢!
看來首先得看看這個(gè)err的原始信息是什么? 于是在catch代碼塊的開頭先console.log一下這個(gè)err:
然后這個(gè)異常信息被打印出來了:
報(bào)錯(cuò)如下:
get Err==> TypeError: Cannot read property 'sort' of undefined
? ? at Object.module.exports [as module] (D:\VueCode\VueProject\myqqmusic\src\registerRouter\NetEaseApi\modules\song_url.js:33:10)
? ? at processTicksAndRejections (internal/process/task_queues.js:93:5)
? ? at async D:\VueCode\VueProject\myqqmusic\src\registerRouter\NetEaseApi\routes.js:69:40
?
?但是為什么把err賦值給msg就取不到值呢,然后斷點(diǎn)調(diào)試看了一下這個(gè)error的數(shù)據(jù)結(jié)構(gòu):
?然后結(jié)合GPT分析了一下,按理說: 通過err.message和err.stack應(yīng)該可以獲取到異常的具體信息:
?然后確實(shí)看到了異常的具體信息了,這回沒有報(bào)空值{}:
?
?好了,小結(jié)一下:Javascript中Error對(duì)象必須通過message或者stack屬性來獲取到具體信息,
也就是err.message或者err.stack這種形式,不能把Error對(duì)象直接賦值給變量!??!否則變量獲取的值就是空對(duì)象!
但是這種報(bào)錯(cuò)信息太難看了,應(yīng)該根據(jù)報(bào)錯(cuò)指引,找到異常被觸發(fā)的地方:
get Err==> TypeError: Cannot read property 'sort' of undefined
? ? at Object.module.exports [as module] (D:\VueCode\VueProject\myqqmusic\src\registerRouter\NetEaseApi\modules\song_url.js:33:10)
? ? at processTicksAndRejections (internal/process/task_queues.js:93:5)
? ? at async D:\VueCode\VueProject\myqqmusic\src\registerRouter\NetEaseApi\routes.js:69:40
?根據(jù)上面報(bào)錯(cuò)信息,找到song_url.js第33行:
這個(gè)地方說result沒有sort屬性,那么result本身極有可能也是個(gè)undefined!
所以非常有必要看看它的父級(jí)res到底是個(gè)什么東西
然后通過斷點(diǎn)調(diào)試可以看到res底下果然沒有data屬性,那么result就必然是個(gè)undefined了,
難怪result.sort會(huì)觸發(fā)Cannot read property 'sort' of undefined異常了
而且這里可以看到引發(fā)異常的真實(shí)原因:
// 這個(gè)異常信息是放在res.body里面的
?{
? code: -460,
? message: "網(wǎng)絡(luò)太擁擠,請稍候再試!",
}
?所以在通過res.body.data獲取result之前,要先判斷一下res.body是否有data這個(gè)屬性,
或者說判斷res的返回狀態(tài)是否正常,因?yàn)閮H僅根據(jù)res.body是否有data屬性來判斷返回是否正常有點(diǎn)太片面了
然后,我找了一個(gè)請求成功的例子:
可以看到請求成功的時(shí)候:不僅res.body有data屬性,res.body.code還等于200,
所以應(yīng)該增加以下代碼:在res請求失敗的時(shí)候主動(dòng)拋出異常,并將res.body作為異常信息:
if (res.body.code != 200 ) { ? ?
? ? throw new Error(res.body)? ?// 因?yàn)楫惓5脑斍樾畔⑹谴鎯?chǔ)在res.body里面
? }
但是在前面說的外部異常攔截的地方(catch err代碼塊),得到結(jié)果是:msg沒能正確解構(gòu)出異常的信息,顯示的是:?[object Object]
?
?
?關(guān)于這個(gè)問題,我查了很久也查了很多資料,嘗試了很多次,都沒有能夠解決問題。
可以說:這是這次問題排查中難度最大的地方
然后呢,我就嘗試著從chatgpt對(duì)話,希望能找到答案。
最初按照它給的方法試了好幾次,也還是不行。
最后我問了一個(gè)關(guān)鍵的神提問:
你沒懂我意思,比如原始異常的信息是res.body="{"code":-460,"message":"網(wǎng)絡(luò)太擁擠,請稍候再試!"}" ,然后我throw new Error(JSON.stringify(res.body)) 拋出了這個(gè)異常,我問catch的時(shí)候怎么才能把這json格式的異常信息取出來
?然后chatgpt終于給出了正確的回答:
我明白你的問題了。如果你的異常信息是一個(gè)JSON字符串,你可以在
catch
塊中使用JSON.parse
來解析它,以獲取原始的JSON對(duì)象。以下是一個(gè)示例:try { const res = { body: '{"code":-460,"message":"網(wǎng)絡(luò)太擁擠,請稍候再試!"}' }; throw new Error(JSON.stringify(res.body)); } catch (error) { try { // 嘗試將異常消息解析為JSON const errorData = JSON.parse(error.message); console.log("Error code:", errorData.code); console.log("Error message:", errorData.message); } catch (parseError) { // 處理解析JSON失敗的情況 console.error("Error parsing JSON:", parseError); } }
在這個(gè)示例中,我們首先拋出一個(gè)異常,異常消息是JSON字符串。然后在
catch
塊中,我們嘗試使用JSON.parse
將異常消息解析為JSON對(duì)象,并訪問其中的屬性。如果解析失敗,我們捕獲到解析錯(cuò)誤并進(jìn)行處理。這樣你就可以獲取到原始的JSON對(duì)象信息了。但要小心處理JSON解析失敗的情況,因?yàn)楫惓O⒉灰欢偸怯行У腏SON字符串。
這里的關(guān)鍵有兩點(diǎn):
1.? 自定義異常信息時(shí): new Error構(gòu)造函數(shù)通常接收一個(gè)字符串作為錯(cuò)誤信息的參數(shù),而不是一個(gè)對(duì)象。
如果是接收參數(shù)是對(duì)象則必須通過JSON.stringify()方法轉(zhuǎn)換成json字符串
2. 當(dāng)已預(yù)知捕獲的error是json字符串時(shí),那么此時(shí)必須使用JSON.parse()方法把error.message轉(zhuǎn)換成object對(duì)象,否則打印出來的就是[object Object]
?所以,代碼需要這樣修改:
異常主動(dòng)拋出的部分:
? if (res.body.code != 200 ) {
? ? // 注意這里new Error的參數(shù)不能是對(duì)象,而必須是字符串?。?!
? ? // 所以res.body必須通過JSON.stringify轉(zhuǎn)成字符串
? ? throw new Error(JSON.stringify(res.body)) ?
? }
?異常捕獲的地方:
catch (err) {
? ? ? ? ? ? ? ? // 因?yàn)閑rr.message是JSON字符串,必須通過JSON.parse轉(zhuǎn)換成對(duì)象,
? ? ? ? ? ? ? ?// 否則msg: errData賦值時(shí)就會(huì)變成: Error: [object Object]
? ? ? ? ? ? ? ? // 這樣msg就獲取不到值,變成了空值了
? ? ? ? ? ? ? ? const errData = JSON.parse(err.message)? //關(guān)鍵點(diǎn) :必須使用?JSON.parse方法
? ? ? ? ? ? ? ? console.log("Error message:", errData.message);? ? ? ?
? ? ? ? ? ? ? ? console.log("get Err==>", err)
? ? ? ? ? ? ? ? console.log('[ERR]', decode(req.originalUrl), {
? ? ? ? ? ? ? ? ? ? status: err.status,
? ? ? ? ? ? ? ? ? ? body: err.body,
? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? if (!err.body) {
? ? ? ? ? ? ? ? ? ? res.status(500).send({
? ? ? ? ? ? ? ? ? ? ? ? code: 500,
? ? ? ? ? ? ? ? ? ? ? ? data: null,
? ? ? ? ? ? ? ? ? ? ? ? msg: errData, ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? ? ? return
? ? ? ? ? ? ? ? }
問題解決:前臺(tái)msg信息終于正常顯示出來了,不再是[object Object]
?
?總結(jié):
1.?Javascript中的Error對(duì)象必須通過message或者stack屬性來獲取到它的具體信息,
也就是err.message或者err.stack這種形式。
不能把整個(gè)Error對(duì)象直接賦值給變量?。。?span style="background-color:#ffd900;">否則變量獲取的值就是空對(duì)象!
2.??自定義異常信息時(shí): new Error構(gòu)造函數(shù)通常接收一個(gè)字符串作為錯(cuò)誤信息的參數(shù),而不是一個(gè)對(duì)象。
如果是接收參數(shù)是對(duì)象則必須通過JSON.stringify()方法把該對(duì)象轉(zhuǎn)換成json字符串
// 主動(dòng)拋出異常的部分
//?如果是接收參數(shù)是對(duì)象則必須通過JSON.stringify()方法把該對(duì)象轉(zhuǎn)換成json字符串
new Error(JSON.stringify(err_obj))
3. 當(dāng)已預(yù)知捕獲的error是json字符串時(shí),那么此時(shí)必須使用JSON.parse()方法把error.message轉(zhuǎn)換成object對(duì)象,否則打印出來的就是[object Object]
// 捕獲異常的部分
catch(err) {
// 當(dāng)已知err是json字符串時(shí),則必須使用JSON.parse()方法把error.message轉(zhuǎn)換成object對(duì)象,否則打印出來的就是[object Object]
? ?errData = JSON.parse(err.message)? // 使用JSON.parse方法是關(guān)鍵!文章來源:http://www.zghlxwxcb.cn/news/detail-718790.html
}文章來源地址http://www.zghlxwxcb.cn/news/detail-718790.html
到了這里,關(guān)于解決node項(xiàng)目一個(gè)極度困難的捕獲異常卻無法讀取異常信息的問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!