在大型軟件項目中如何處理錯誤和異常


我在測試中沒有發現bug,所以系統沒有bug,對吧?

不幸的是,大規模的軟件太復雜,無論多少測試都無法做到沒有bug。你無法對用戶使用應用程序的所有不同方式進行測試。因此,理解應用程序中錯誤和異常的區別是非常重要的,同時要了解處理它們的正確方法,以便你可以采取主動的方式為開發團隊和終端用戶提供健康的應用程序。

測試的局限性

即使使用最徹底的測試過程,仍然只是在測試特定的情況,並且包含了自己的想法在其中。

想象一下,突然有成千上萬的用戶以你沒有想到的方式使用你的應用程序——他們幾乎肯定會碰到你在測試時沒有碰到的東西。

如何正確處理應用程序中的錯誤

簡單地說,bug可以導致錯誤和異常。錯誤和異常是有不同含義的術語。

主要的問題應該是如何更好地處理這些錯誤和異常,使它們不會產生負面后果。

首先,讓我們看看一些定義,以及為什么這些區別很重要。

錯誤和異常——有什么區別?

一些編程語言有它們自己的錯誤和異常定義,但是我想定義它們的區別。

錯誤

無法優雅地恢復/繼續的編程錯誤,通常需要開發人員介入並修改代碼來進行修復。有時可以將錯誤轉換為異常,以便在代碼中處理它們。

通過簡單檢查可以避免錯誤,如果簡單檢查不能滿足要求,錯誤還可以轉化為異常,以便應用程序能夠優雅地處理這種情況。

異常

利用特定語言的語義,並在發生異常時表示。異常可以被捕獲和拋出,以便代碼可以恢復和處理這種情況,而不進入錯誤狀態。

可以拋出和捕獲異常,以便應用程序能夠正常恢復或繼續。還可以記錄未處理的異常(即錯誤),以便開發人員查看它們以修復底層錯誤。

示例# 1

用戶錯誤——用戶輸入錯誤數據,也不需要異常處理,但仍可能導致錯誤/不可恢復狀態。代碼應該進行簡單的檢查,以防止發生這種情況。應該使用前端和后端驗證,對於本例,只拋出一個異常作為“最后的防御”。

示例# 2

文件無法打開並拋出FileLoadException或FileNotFoundException。這是一種特殊情況,不應該破壞應用程序。應用程序應該能夠處理這種情況,因為這種情況可能由於許多原因而發生,因此,你必須預期到這種情況。

該出錯的還是會出錯……至少一次

“所以……如果我捕捉到每個異常,我的代碼就不會出錯了,對吧?”

正如我前面提到的,並非所有錯誤都會導致異常。這個結論的主要問題是你不知道哪里出了問題。你的代碼可能存在許多問題,由於捕獲異常而對其不做任何處理,你會丟失這些信息。

不要只是捕捉每個異常,然后繼續,就像什么都沒有發生過一樣。捕獲塊的目的是在一定情況下進行處理。

不要做什么——把他們捕獲起來。

如何編寫應用程序來恢復自己

拋出和捕獲異常是讓應用程序自行恢復並防止它運行到錯誤狀態的好方法。

如果你知道可能會拋出哪一種類型的異常,最好在catch塊中顯式地顯示,因為每種不同類型的異常都將意味着代碼由於不同的原因而停止。

異常類型要具體,這樣就可以向用戶提供反饋,並在確切知道失敗的原因后更優雅地處理其他情況。

為什么指定要捕捉哪種類型的異常很重要?

某些異常可能破壞數據或以意外的方式運行,這取決於你的程序如何繼續運行。這將導致應用程序出現錯誤。

如果你確切地知道發生了哪種異常,那么你應該知道要按照哪些步驟進行恢復。或者,如果無法恢復,你應該知道如何優雅地處理這種情況。

那么,它能恢復嗎?在很多情況下,異常具有足夠的信息來知道發生了什么錯誤,並且在catch塊中,你有時可以從錯誤狀態中恢復。可以通過修復一些數據、重新獲取數據或甚至要求用戶再試一次。

你可以捕獲異常,但有時應用程序仍然無法繼續運行,因為它所依賴的數據已經以不可恢復的方式被損壞,或者它期望數據采用不同的格式。

示例

數組上的OutOfRangeException異常?一個程序如何才能恢復?這是一個將錯誤轉化為異常的例子。你的應用程序期望數據以某種方式出現,但這並沒有發生。雖然恢復並不總是可能,但現在可能不進入錯誤狀態並優雅地處理這種情況。如果將此記錄下來,開發人員可以通過在訪問數組之前添加一些簡單的檢查或更改訪問它的方式來修復此問題。

如何處理未處理的異常

有一些你意想不到的異常,通常表示代碼中的錯誤。你可以記錄那些沒有被代碼捕獲的未處理的異常,因為大多數語言都提供了這樣做的方法。任何未處理的異常都表示錯誤。你的代碼沒有預料到這一點,因此無法正常恢復或處理這種情況。

將它們記錄下來是一個好主意,這樣就可以修復。這樣,錯誤就不會經常拋出異常。如果它們真的發生了,你想要了解它們,這樣你就可以捕獲它們並處理它們。

錯誤日志

錯誤日志可以幫助捕獲這些錯誤。有一個可以查看這些日志錯誤/異常的地方是調試的關鍵,也是確定何時修復什么問題的優先級。

此外,你也不希望依賴於屏幕截圖和已經沮喪的用戶提供的更多信息。錯誤日志記錄還可以使你的團隊在出現錯誤時能夠積極主動地聯系受影響的用戶。這是為了讓他們知道你正在解決問題,這不僅會促進你的客戶關系,而且你還可以在其他用戶遇到錯誤之前修復錯誤。

示例

代碼中產生多個不正確的賬單費用的錯誤通常比無法顯示特定詳細信息頁面的錯誤更重要,即使詳細信息頁面錯誤發生得更頻繁。

最終,你希望應用程序遇到的異常盡可能少,但是當它遇到異常時,你希望了解它。只有1%的用戶報告錯誤,所以還有很多錯誤仍然存在。

解決部分問題

編寫一些代碼將異常和堆棧保存到文件中,或者通過電子郵件發送,以便在發生錯誤時得到通知,這可能是部分解決方案。

示例

一個用戶會遇到上千個異常。100個用戶也遇到了較少發生的錯誤。哪個更重要?在不知道錯誤細節的情況下,影響更多用戶的錯誤更重要。

使用異常的堆棧應該有助於定位錯誤可能出現的位置,並且你應該能夠重新生成它或閱讀代碼以理解那里出了錯。

有時這還不夠,問題需要進一步調查。如果發生這種情況,在記錄異常之前向異常添加更多信息,包括上下文特定細節(例如帳戶id或特定對象狀態),這些信息將允許你在本地重新生成錯誤。

是時候修正錯誤了

現在,你應該已經捕獲了所有的錯誤和異常,並記錄未處理的錯誤……現在該怎么辦呢?

根據應用程序的規模,錯誤通知中的噪音是一個問題。你可以使用電子郵件過濾/grep做一些聰明的事情,它可以分組錯誤並分離到不同的文件夾/文件中。這可能有所幫助,但只是對噪音問題的部分解決方案。

幾年前,我個人也這么做過,但很快意識到這只是一個部分的解決方案,原因有很多。問題是,我仍然不知道哪些錯誤對用戶的影響最大。我關注的是那些拋出的錯誤,而不是那些對應用程序/用戶體驗最有害的錯誤——正因為如此,我從未真正清楚地知道哪里出了問題。

我無法看到發生了什么,但必須運行手動查詢才能弄清楚,這非常耗時。

對於大型軟件,總是會拋出錯誤和異常。正確地處理錯誤將有助於將你定義為一個軟件團隊,並圍繞異常和錯誤創建更好的過程。

好的應用程序包含可以在可能的情況下從異常中恢復的代碼。處理和記錄異常對軟件的運行狀況非常重要!

 歡迎關注我的公眾號,如果你有喜歡的外文技術文章,可以通過公眾號留言推薦給我。

原文鏈接:https://dzone.com/articles/how-to-handle-errors-and-exceptions-in-large-scale


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM