Pete Goodliffe
太多程式設計師忽略錯誤#
我走在路上要去酒吧見朋友。匆忙之中,我被路緣絆倒,臉朝下摔了一跤。腿很痛,但我趕著見朋友,就繼續走。走得越遠,痛得越厲害。到了酒吧,我因為太分心而沒有好好享受。隔天早上去看醫生,發現脛骨骨折了。如果我當時停下來,就能避免繼續走路造成的額外傷害。
太多程式設計師寫程式就像作者那次糟糕的夜出——「錯誤?不會很嚴重吧。我可以忽略它。」 這不是一個可靠程式碼的策略,這只是懶惰(而且是錯誤的那種)。
永遠檢查,永遠處理#
無論你認為程式碼中出錯的可能性有多低,你都應該永遠檢查並處理錯誤。每一次。你不是在節省時間,而是在為未來埋下隱患。
錯誤回報的常見方式#
我們在程式碼中以多種方式回報錯誤:
- Return codes(回傳值)——用函式的回傳值來表示「失敗」。錯誤回傳碼太容易被忽略了。你多常檢查
printf的回傳值? - errno——C 語言一個特殊的全域變數。容易被忽略、難以使用,在多執行緒環境中還可能造成問題
- Exceptions(例外)——一種更結構化的、語言支援的錯誤處理方式。你不可能忽略它們……真的嗎?常見的反模式:
這個結構唯一的「優點」是清楚地表明你在做一件道德上有問題的事。try { // ...do something... } catch (...) {} // ignore errors
忽略錯誤的後果#
如果你忽略一個錯誤、視而不見、假裝什麼都沒發生,你就是在冒很大的風險。就像作者的骨折一樣,如果當時就處理,本可以避免更多的傷害。
不處理錯誤會導致:
- 脆弱的程式碼(brittle code)——充滿令人興奮的、難以追蹤的 bug
- 不安全的程式碼(insecure code)——駭客經常利用糟糕的錯誤處理來入侵系統
- 糟糕的結構(poor structure)——如果你的程式碼中充滿了處理起來很煩人的錯誤,你的介面可能設計得不好。讓錯誤處理更不突兀、更不繁重
你需要在介面中暴露所有潛在的錯誤狀態。不要隱藏它們,不要假裝你的服務永遠正常運作。在最早的機會處理問題,保持短帳。
常見的藉口#
為什麼我們不檢查錯誤?常見的藉口包括:
- 錯誤處理會打亂程式碼的流程,讓「正常」的流程更難閱讀
- 這是額外的工作,而我有截止日期
- 我知道這個函式呼叫永遠不會回傳錯誤
- 這只是個玩具程式,不需要寫成生產品質
這些藉口都站不住腳。每次你遇到錯誤處理的問題時,反駁這些藉口,然後正確處理錯誤。