線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:5643
推到 Plurk!
推到 Facebook!

關於錯誤訊息及Exception的處理?

尚未結案
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-05 14:33:18 IP:219.80.xxx.xxx 未訂閱
我的程式碼如下: 有時會在紅字那行出現錯誤.
Times=0;
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  try
  { 
   if ((Now().FormatString("ss"))%60==0)
     {
      Timer1->Enabled=false;
      _di_IGEDGatewayToClient abc;
      HTTPRIO1->QueryInterface(abc);
      abc->Send(Times);
      Times++;
      Timer1->Enabled=true;
     }
  }
  catch(...)
  { 
   Memo1->Lines->Add(".............");
   Memo1->Lines->Add("Error...Retry...");
   abc->Send(Times);
  }
}
0.因為不曉得會有什麼exception,所以使用catch(...) 1.請問該如讓出現錯誤的那行繼續執行一次,直到他成功為止? 2.上面藍色那行,如何順便顯示錯誤訊息於Memo1上? 3.不讓錯誤時中斷程式執行,一定要將設定Tools->Debugger Options->Language Exceptions下方「Stop on Delphi Exceptions」、「Stop on C++ Exceptions」這兩項的打勾給取消嗎? 4.上面程式紅字出現的錯誤訊息如下: 5.於出現錯誤的那行裡使用了try catch,但是錯誤情況一樣發生,程式一樣中斷,請問我該如何修改才正確? 謝謝. 發表人 - nlj859 於 2004/09/05 16:13:34
seeing
初階會員


發表:49
回覆:131
積分:41
註冊:2002-11-07

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-06 08:46:33 IP:140.134.xxx.xxx 未訂閱
您好:     請問您是在Debug模式下執行程式的嗎?因為據小弟所知,try...catch 必須是直接執行程式,而不是透過BCB的編譯後來執行的。如果是在Debug模式下執行,那麼就算有加了 try...catch ,遇到錯誤的時候還是會發生中斷,無法將 try...catch 的功能真正發揮出來        請多多指教!!
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-06 13:21:17 IP:219.80.xxx.xxx 未訂閱
Hello, 我是在直接執行程式的狀況下,但是就是catch不到exception,不曉得是不是我catch錯地方還是怎樣... 知道的人給我一點建議吧. 謝謝.
bigdogchina
版主


發表:238
回覆:523
積分:312
註冊:2003-04-28

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-06 20:12:56 IP:211.162.xxx.xxx 未訂閱
不好意思,插個花: 小弟的一點淺見,還請各位批評: 先來看一個C的例子:

#include 
FILE *fp;
fp = fopen("test.txt","r");
if(fp == NULL)
{
        printf("不能打開文件!\n");
        exit(0);
}
上面的程式中,如果fopen()函數返回了NULL值,那麽就可以認爲打開文件的操作失敗了。這是C中通常的做法,但是這樣有幾點不太好:首先,一個健壯的程式要考慮許多會使程式失敗的因素,如果對每個因素都進行如上面那樣的條件判斷,那麽整個程式的結構必然變得很混亂。其次,可能函數的所有返回值都是合法的,從而找不到一個表示錯誤的方法。最後,有些函數可能根本就不返回任何值(C 中的構造函數和析構函數) 那我們是不是找另外一種處理錯誤的方法,它應該有以下幾個特定: ⑴不要打亂程式的結構,如果沒有任何錯誤産生,那麽程式的運行將不受任何影響 ⑵不依靠函數的返回值來報告錯誤是否産生 ⑶即使採用集中的方式處理錯誤,也能夠根據錯誤種類的不同來進行錯誤處理操作 具體的來看看C (當然包含BCB和一切符合C 標準的編譯器哦)將怎樣做到以下幾點:

#include 
#pragma hdrstop    #pragma argsused
using namespace std;
int main(int argc, char* argv[])
{
        double * data;
        try
        {
            data = new double[1000];
        }
        catch(std::bad_alloc)       //std::bad_alloc是new操作符唯一能引發的異常
        {
            cout<<"不能分配記憶體"<
可見我們將所有可能産生異常的語句包含在try塊中,並在隨之而來的catch語句總捕獲發生的異常。一個try快後可以跟隨幾個不同的catch語句,用來捕獲不同的異常。如果希望捕獲任何可能發生的異常,應該使用catch(...)語句。如果我們希望在封裝成一個自己的異常類,則:

class Out();
int main(int argc, char* argv[])
{
        try
        {
            throw Out();   //抛出一個臨時的Out物件
        }
        catch(Out & e)     //捕獲Out異常
        {
            cout<<"Out的異常已被捕獲"<
利用關鍵字throw可以抛出任意的物件,這個物件不需要繼承exception類。即使是基本資料類型,也可以作爲throw的參數而被抛出。在catch的參數中如果包含一個變數聲明的運算式,就可以在catch塊中使用這個異常類。如果在catch塊中處理完一個異常類之後,異常造成的後果並不能完全消除,那麽可以在catch語句中再次調用catch語句,從而使得捕獲的異常向外層傳播。如果在一個函數中沒有處理發生的異常,那麽異常將會傳播到調用此函數的代碼段中. 您還可以參考小弟在下面這篇中的討論: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=53541 參考文獻:"C Primer" ================================= 人生在勤,不索何獲 業精於勤荒於嬉,行成於思毀於隨 臨淵羡魚不如退而結網
------
人生在勤,不索何获?
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-06 22:01:19 IP:211.76.xxx.xxx 未訂閱
bigdogchina做了一個精闢的見解 我也來提出一些拙見~~ >。 因種種以上的原因,有人提出以下的>使用> 例如記憶體不足:像>使用> 例如有些程式在一開始時,會先向系統要求一大塊記憶體, 隨後在遇上 > 以上是一些心得 煩請大家批評討論...
andychang1690
資深會員


發表:20
回覆:694
積分:442
註冊:2003-03-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-09-08 04:49:44 IP:221.169.xxx.xxx 未訂閱
nlj859你好: 可否請教你的abc->Send(Times); 是否是ClientSocket或是其他? Andy Chang
------
Andy Chang
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-09-08 11:46:29 IP:219.80.xxx.xxx 未訂閱
Hello, 使用HTTPRIO元件,呼叫遠端service. _di_ItoClient abc; HTTPRIO1->QueryInterface(abc); abc->Send(Times);
andychang1690
資深會員


發表:20
回覆:694
積分:442
註冊:2003-03-14

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-09-08 21:07:01 IP:221.169.xxx.xxx 未訂閱
nlj859:對不起我使用BCB5並沒有WebServices組件,但請試試以下方式可否
攔截到錯誤訊息,再行處理OK!
試試於.hpp檔加入
public:                // User declarations
        __fastcall TFormMain(TComponent* Owner);
        void __fastcall HandleExceptions(TObject *Sender, Exception *E);
.cpp檔
void __fastcall TFormMain::FormCreate(TObject *Sender)
{
  // 設定exception handler.自定義異常處理窗口
  Application->OnException = HandleExceptions;
}
void __fastcall TFormMain::HandleExceptions(TObject *Sender, Exception *E)
{
  if (E->Message.Length())
  {
    Screen->Cursor = crArrow;
    AnsiString errorstr="應用程序發生了錯誤.\n" E->Message;
    Application->MessageBox(errorstr.c_str(),"發生異常",MB_OK);
  }
}
請參考。
Andy Chang
------
Andy Chang
powerhowardchen
初階會員


發表:15
回覆:28
積分:28
註冊:2004-04-19

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-09-21 17:56:12 IP:61.70.xxx.xxx 未訂閱
用 SetErrorMode(SEM_FAILCRITICALERRORS); 吧! (加在主程式的開頭) 這樣, 所有的錯誤訊息就都會被導到Exception物件, 就不會再有錯誤訊息出現了. 其實, 我覺得 Exception 滿好用的, 既可用來分類錯誤類型, 以及自訂錯誤類型, 又可攜帶錯誤的原因、相關物件、數值、資料等, 他可以簡化程式設計的複雜度, 能容易的跳離後續處理的程式, 不必再寫一大堆的錯誤判斷式, 更不再需要將錯誤情形與錯誤碼分別傳回(所以 Windows 才用 GetLastError(), 因為Windows不能預期使用API的程式能不能接收Exception); 我個人認為, Indy的做法很好, 讓我可以很清楚的知道錯誤原因, 至於要不要略掉或是要處理錯誤, 就都在於我囉. ================================================== Howard Chen. Delphi, Java 我的神..... .NET 垃圾筒在哪裡?...
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-09-22 12:35:18 IP:219.80.xxx.xxx 未訂閱
引言:
nlj859:對不起我使用BCB5並沒有WebServices組件,但請試試以下方式可否
攔截到錯誤訊息,再行處理OK!
試試於.hpp檔加入
public:                // User declarations
        __fastcall TFormMain(TComponent* Owner);
        void __fastcall HandleExceptions(TObject *Sender, Exception *E);
.cpp檔
void __fastcall TFormMain::FormCreate(TObject *Sender)
{
  // 設定exception handler.自定義異常處理窗口
  Application->OnException = HandleExceptions;
}
void __fastcall TFormMain::HandleExceptions(TObject *Sender, Exception *E)
{
  if (E->Message.Length())
  {
    Screen->Cursor = crArrow;
    AnsiString errorstr="應用程序發生了錯誤.\n" E->Message;
    Application->MessageBox(errorstr.c_str(),"發生異常",MB_OK);
  }
}
請參考。
Andy Chang
請問該如何去處理攔截到的訊息? 可否舉例一下? 謝謝.
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-09-22 12:37:51 IP:219.80.xxx.xxx 未訂閱
引言: 用 SetErrorMode(SEM_FAILCRITICALERRORS); 吧! (加在主程式的開頭) 這樣, 所有的錯誤訊息就都會被導到Exception物件, 就不會再有錯誤訊息出現了. 其實, 我覺得 Exception 滿好用的, 既可用來分類錯誤類型, 以及自訂錯誤類型, 又可攜帶錯誤的原因、相關物件、數值、資料等, 他可以簡化程式設計的複雜度, 能容易的跳離後續處理的程式, 不必再寫一大堆的錯誤判斷式, 更不再需要將錯誤情形與錯誤碼分別傳回(所以 Windows 才用 GetLastError(), 因為Windows不能預期使用API的程式能不能接收Exception); 我個人認為, Indy的做法很好, 讓我可以很清楚的知道錯誤原因, 至於要不要略掉或是要處理錯誤, 就都在於我囉. ================================================== Howard Chen. Delphi, Java 我的神..... .NET 垃圾筒在哪裡?...
請問可否舉例一下使用方法呢? 謝謝.
powerhowardchen
初階會員


發表:15
回覆:28
積分:28
註冊:2004-04-19

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-09-23 15:58:49 IP:61.70.xxx.xxx 未訂閱
從你ㄧ開始問的問題回答.... > 0.因為不曉得會有什麼exception,所以使用catch(...) A: 要攔截 Exception , 可以用 catch(Exception &e), 就幾乎都可以欄到了, 而 e 就是丟出的錯誤訊息物件. > 1.請問該如讓出現錯誤的那行繼續執行一次,直到他成功為止? A: 可以做一個循環判斷程式, 請參考範例. > 2.上面藍色那行,如何順便顯示錯誤訊息於Memo1上? A: 從問題 0 的作法中, 取得的 e 物件就會有錯誤訊息內容, 可以在 catch 內用 Memo1->Lines->Add(e.ClassName() ":" e.Message); 即可. 我喜歡將 ClassName() 顯示出來, 這樣我就很容易可以知道 Excpetion 的類型, 方便我在改程式時, 加上 Exception 類型的判斷處理. > 3.不讓錯誤時中斷程式執行,一定要將設定Tools->Debugger Options->Language Exceptions下方「Stop on Delphi Exceptions」、「Stop on C Exceptions」這兩項的打勾給取消嗎? A: 你也可以設定 "Exception Types to Ignore", 當取得了 Excpetion 的物件類型後, 將該類型加入 Ignore 清單中即可. 通常, 我是都將該項目打勾, 讓錯誤都 Ignore 掉, 等到有錯誤訊息被發現時, 才開起來做偵錯. 原本 Delphi 2 版中, 對於程式中已經被程式所攔截的 Exception 都會直接被 Ignore 而不會讓 Delphi 顯示, 可是 Delphi 3 起就都會被顯示了, 我認為這樣是好的, 因為當 Exception 被觸發(raise 或是 throw)時, 要讓 Debug 程式(Delphi) 去判斷該程式會不會在"未來"去攔截此一 Exception, 是很容易出錯的. > 4.上面程式紅字出現的錯誤訊息如下: A: 這是 BCB 攔截錯誤後所顯示的訊息. 就看你要不要採用問題 3 的作法囉. > 5.於出現錯誤的那行裡使用了try catch,但是錯誤情況一樣發生,程式一樣中斷,請問我該如何修改才正確? A: 你可以把 SetErrorMode(SEM_FAILCRITICALERRORS); 這行寫在這個函式的剛開始的位置(要在try之前), 這樣系統就只會把錯誤訊息網你這兒送, 不會自己Show出來. 用 SetErrorMode 只是避免 Windows(OS) 自己去顯示錯誤而不讓該程式去攔截(像是軟碟片沒插入, 磁碟機異常等), 但是你在問題 4 的情況則是正常的, 就看你要不要設定罷了. ================================================== Howard Chen. Delphi, Java 我的神..... .NET 垃圾筒在哪裡?...
powerhowardchen
初階會員


發表:15
回覆:28
積分:28
註冊:2004-04-19

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-09-23 16:01:25 IP:61.70.xxx.xxx 未訂閱
範例: // SendData 是你要傳送的資料, TimeOutMS 是總共容許傳送的時間(千分之ㄧ秒 ms) void __fastcall TForm1::AdvSend(void *SendData, DWORD TimeOutMS) { DWORD BeginTick = GetTickCount(); String ErrorMsg; SetErrorMode(SEM_FAILCRITICALERRORS); while (GetTickCount() - BeginTick < TimeOutMS) { ErrorMsg = ""; try { abc->Send(*SendData); break; } catch(Exception &e) { ErrorMsg = e.ClassName() ":" e.Message; } } if (ErrorMsg != "") throw Exception(ErrorMsg); } void __fastcall TForm1::Timer1Timer(TObject *Sender) { try { if ((Now().FormatString("ss"))`==0) { Timer1->Enabled=false; AdvSend(&Times, 10000); Times ; Timer1->Enabled=true; } } catch(Exception &e) { Memo1->Lines->Add("Send fail. Error Detail: " e.Message); } } ================================================== Howard Chen. Delphi, Java 我的神..... .NET 垃圾筒在哪裡?...
系統時間:2024-03-29 0:55:52
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!