錯誤處理在程式設計中是很重要的,可以在除錯,發布的時候少了很多麻煩,以往在做軟體的時候總是少了錯誤處理,導致使用者用來莫名其妙,在查詢問題的時候也是沒有頭緒
最近在總結一些錯誤處理技巧,總共有這麼一些方法:
1.log
log在關鍵的時刻可以救命的東西,因此我一直提議組裡的人多使用log,但是log記多了也不好,會導致混雜資訊太多
之前公司裡面有個3d的寫log太頻繁,結果導致執行8小時就寫了4g的log導致執行崩潰,當時給他找了好多天才發現是log的問題
先階段來說,我們的log主要是用在處理輸入輸出上面,因此我建議在以下幾個地方記錄log:
1.1 與外部庫最近互動的地方
這裡的外部庫就是非本公司所使用的開發庫,比如我們公司使用的boost, qt這些庫
1.2. io輸入輸出的資料
主要是網路,檔案,串列埠這些資訊,記錄資訊的時候除了有乙份二進位制的原始資料以外,最好還附帶乙份視覺化的資料
1.3. 邏輯處理的地方
這個就比較難以界定了,其實到現在我沒法很好地記錄這方面的資料,但是我的建議是,如果這個邏輯處理是和外部互動的,比如網路,串列埠,一定要把這個邏輯給記錄下來
2.錯誤值返回
錯誤值返回是比較古老的方式,好處程式是按照流程來處理的,壞處就是在if內嵌if的時候**看起來會很雜亂,不過有do..while(false)這個技巧可以避免
3.異常處理
異常處理在c++裡面是比較爭議的一種方式,最近在專案裡面我也開始使用異常處理,所以感慨比較多,但是給我的感覺就是這個不是用在錯誤處理的,之前看c++之父寫的那本書的時候,他也提到過這一點,他是在處理異常而不是來處理錯誤的,很多c++的書都告訴使用者異常處理是代替c語言方式的返回值的,但是c++之父強調了兩點:
1.異常處理是用來處理異常的,這些異常需要是可恢復的
2.異常處理是用來解決建構函式無法報告錯誤的
但是怎麼界定錯誤和異常這個我到現在還是沒法好好地界定
之前書上很多都也都不建議使用異常,因為c++裡面沒有gc,但是我們可以使用raii以及boost_exit和shared_ptr(其實也是raii)來解決問題
因為好像在現代c++裡面,好像沒什麼理由再不使用異常了
在之前用python的時候,python大部分都是利用異常來處理錯誤,python使用異常處理,我一直覺得這種方法不錯,但是python本身的異常型別也有點多,如果要在c++裡面模仿這種方法,我們必須要定義很多異常型別,否則無法把足夠的異常資訊帶給外部,但是這樣會造成的檔案依賴
比如最近我在寫乙個函式,這個需要將乙個格式的檔案轉換成對應的資料儲存到sql裡面,需要做如下動作:
在每乙個動作的時候,如果發生錯誤,我們都需要報告給外部知道發生了什麼錯誤,以便於使用者去處理
1.讀取原始檔
1.1 檔案不存在
2.讀取對應的資料
1.1 檔案格式錯誤,或者缺少資料
3.根據對應的資料去讀取對應的
1.1 不存在,或者格式錯誤
4.建立對應的sql檔案
1.1 sql檔案本身已經存在,需要詢問使用者究竟是代替掉還是取消這個行為??
5.建立對應的表
1.1 建立表錯誤
6.將對應的資料儲存到sql檔案
1.1 執行一些sql語句發生錯誤,或者讀取對應的的時候發生錯誤,詢問使用者是要無視這個錯誤還是要繼續執行
如果在函式內發生錯誤將會有如下的處理方式:
1.直接返回false,這種型別是無法繼續執行的 (1,2,5)
2.需要詢問使用者是否繼續執行(3,4)
最早的第乙個版本我是使用異常的,但是後來發現,無法去詢問使用者是否繼續執行
然後我改用bool,無法讓外部知道是哪一步出錯了,如果要讓使用者知道哪一步錯誤,需要定義一堆的enum,而且也無法讓外部去詢問
最後我的解決方案是:
把每乙個動作封裝成乙個函式,然後在ui層分成每一步執行,這樣可以達到上面的效果,但是無法將動作封裝成乙個函式
4.coroutine
這個是那天晚上想到的,是為了解決要尋外上面的例子裡面需要詢問外部的,在執行函式的時候傳入乙個coroutine,這樣如果發生錯誤則暫停執行,返回到外部,由外部來決定是否繼續執行
Linux的錯誤處理的一些吐嘈
linux裡面的一些函式很多返回 1 有指標的一般是null 作為錯誤的時候的返回值,同時返回了乙個errno的值。這個值有很多種定義,大家可以在man errno裡面看到。檔案不存在,許可權不夠等等 在posix以前沒引進執行緒概念的時候往往是這樣定義的 extern int errno 但是在多...
一些錯誤的想法和錯誤的感悟
記住,ssl只是乙個傳輸層上的封裝協議,傳輸層上的。它代表的語義一定要比傳輸層更具體而比應用層更不具體。怎麼能拿它來封裝乙個具體應用呢?這是典型的主次顛倒,本末倒置,喧賓奪主的極端做法!https只能在ssl之上,難道能在ssl之下嗎?這裡最重要的是資料邊界問題,你是用你的應用協議來定義資料邊界還是...
MySql錯誤處理 錯誤處理的例子
有幾種錯誤處理的宣告形式 如果任何錯誤 不是 not found 設定 l error 為 1 後繼續執行 declare continue handler for sqlexception set l error 1 如果發生任何錯誤 不是 not found 執行 rollback和產生一條錯誤...