2017-06-29 79 views
1

最近我和同事討論過,關於使用trycatch來通知錯誤或避免錯誤。try-catch是爲了防止還是處理錯誤? (在javascript中)

這是我同事的做法:

import Config from 'config'; 

export const getUserFromLocalStorage =() => { 
    const key = Object.keys(localStorage).find(value => value === `${Config.applicationId}/currentUser`); 

    try { 
    return key ? JSON.parse(localStorage[key]) : {}; 
    } catch (e) { 
    return {}; 
    } 
}; 

Wich means, he doesn't care about the given error and he is just carrying of returning an object in order to continue the process

和我的是:

import Config from 'config'; 

export const getUserFromLocalStorage =() => { 
    const key = Object.keys(localStorage).find(value => value === `${Config.applicationId}/currentUser`); 

    try { 
    return key ? JSON.parse(localStorage[key]) : {}; 
    } catch (e) { 
    console.log('the given error', e); // Just simple notifier for this example 
    } 
}; 

,但我的做法,仍然有一個問題,就是它會返回undefined(這可能會崩潰內置我的應用程序),可以使用finally輕鬆修復它並返回一個默認值,但對我來說聽起來不太好。


問題

那麼將使用trycatchfinally如果需要的話,使我的應用程序穩定的平衡。
我們的方法有什麼問題嗎?
特別是,我們不能信任來自localStorage的數據,那麼這個實現的最佳方法是什麼?

+4

'是它會返回未定義的(可能會導致內部應用程序崩潰)':您應該記錄該方法可能會返回'undefined',並且您的代碼調用它應該能夠處理該問題。同樣,你的同事的空對象可能會導致調用代碼的異常。主要是記錄在錯誤狀態下返回的內容,並讓呼叫者決定要做什麼。 –

+0

不,您不會使用'finally'來爲錯誤情況返回默認值。 – Bergi

+0

@Bergi'finally'的效用是什麼 – JoseAPL

回答

-1

我覺得最重要的是用戶滿意度。在一天結束時,該程序由普通用戶使用。用戶需要使用該程序繼續他的工作,而不會有任何中斷。

所以,我認爲最好的做法是用try運行代碼和catch,如果有任何錯誤,並通知開發者和/或用戶有一個例外,並使用finally通過返回一個有效的目的是克服例外。

這樣用戶也可以繼續工作,開發人員也可以檢查日誌文件中的錯誤以供將來調試。 這是我的個人想法。

3

既然finally在兩種情況下都執行,無論是否引發了某些事情,都不是返回默認值的地方。您是否需要詳細記錄錯誤也是有問題的。這一切都取決於是否預期的錯誤或真正的例外情況誰可以做些什麼。

存儲的值是否可能或可能存在無效的JSON?你有一個「備份計劃」,在這種情況下做什麼?用戶和/或開發人員能做些什麼呢?那麼不要打擾任何人。也許你想給console.log一個可能有助於調試的消息,但除此之外只是繼續執行程序流程。如果a)用戶沒有發起該操作,並且b)他們也沒有什麼要做的,那麼肯定沒有必要使用alert來攻擊用戶。

考慮採取:

  1. 是否catch錯誤在首位:

    • 是它可以在程序流中自然發生的預期誤差?
    • 這是一個錯誤,你可以做些什麼?
    • 你有什麼計劃如果你發現錯誤怎麼辦?
  2. 是否記錄一個錯誤:

    • 該日誌任何人都沒好處呢?
    • 有人會看到這個日誌條目嗎?
    • 它會給任何人提供任何有助於解決問題的有用信息嗎?
  3. 是否錯誤的東西用戶:

    • 沒有用戶發起的行動?
    • 用戶是否期望某種形式的響應,正面還是負面?
    • 用戶可以做任何事情來解決問題嗎?

是否返回一個空對象,或者什麼/ null/undefined取決於函數的責任是什麼。定義的函數是否總是返回一個對象?那麼它應該從catchreturn {}。或者當預期的對象不存在時,「沒有」是有效的迴應?那麼也許return false

總的來說,你的同事的做法對我來說似乎很合理。

+0

好吧,如果由於任何原因,在'localStorage'中有一個無效的JSON對象,我會返回一個空的對象,假設'getUserFromLocalStorage'總是會工作並返回一些(有效),這是「不正確的」?因爲有錯誤,我理解你的解釋。實際上,如果密鑰不存在,我們甚至不應該返回空對象。 我想這一切都取決於'getUserFromLocalStorage'函數的合約。你怎麼看? :) – JoseAPL

+1

錯誤並不總是致命的,這意味着在正常的程序流程中可能會出現錯誤,可以簡單地進行默默處理(在地毯下掃描)。錯誤!==總是敲響警鐘。除此之外,是的,*你*決定你希望你的功能在外部表現如何。 – deceze

+0

謝謝,你應得到一個偉大的解釋和使用情況的賞金:) – JoseAPL

1

在這個特定的情況下,你正在使用localStorage(它幾乎總是不可避免地意味着使用JSON.parse())的工作,所以最好的做法是將你的處理封裝在try-catch中。這是因爲localStorage和JSON.parse都有作爲錯誤處理的正常部分的異常,並且通常可以優雅地回退到默認值或初始值。

我使用的模式是一樣的東西如下:

const DEFAULT_VALUE = {}; 
try { 
    const result = JSON.parse(result); 
    return result || DEFAULT_VALUE; 
} catch (e) { 
    console.warn('Error parsing result', e); 
} 

return DEFAULT_VALUE; 

這樣一來,你有一致的錯誤處理和默認值回退。

一般來說,你不應該需要使用try-catch,除非你能夠並且將安全地處理錯誤併產生有用的回退。由於這個原因,大多數try-catch塊傾向於坐在調用堆棧的底部,以便它們捕獲計劃外錯誤,爲用戶正常處理它們,但將它們用調用堆棧進行威脅地記錄到控制檯以供開發人員使用調查/正確處理/解決方法。

相關問題