4

これは re-raise 例外のサンプルであり、うまく機能しています

  try
    raise Exception.Create('Exception msg');
  except
    on E: Exception do
    begin
      if not(e is EConvertError) then
        raise; // re-raise exception
    end;
  end;

ここに私のカスタマイズ方法があります

//    uses fib //fibplus  EFIBInterBaseError
    procedure CustomizeException(e: Exception);
    var
      s: String;
    begin
      if E is EFIBInterBaseError then
      begin
        if Pos('unique',e.Message)>0 then
        begin
          s := 'record';
          if Pos('CUSTOMMERS_IDX1',e.Message)>0 then
            s:= 'Custommer Number';

          raise TCustomizedException.CreateFmt('The %s is already exists.',[s]);
        end
        else
        if Pos('</CMSG>',e.Message)>0 then
        Begin
          raise TCustomizedException.CreateFmt('%s',
          [StrUtilsEx.GiveInTags(e.Message,'<CMSG>','</CMSG>')]
          );
        End
        else
          raise EFIBInterBaseError.CreateFmt('%s',[e.Message]);
      end
      else
        raise Exception.Create(e.Message);   //e;// e.Create(e.Message);
    end;

しかし

  try
    raise EConvertError.Create('Error Message');
  except on e : exception do
    Begin
      ShowMessage(Format('%s -> %s',[e.ClassName , e.Message])); //(1)
      try
        CustomizeException(e);
      except on e2: Exception do
        ShowMessage(Format('%s -> %s',[e2.ClassName , e2.Message])); //(2)
      end;
    End;
  end;

結果

(1)->EConvertError -> エラーメッセージ

(2) ->例外-> エラーメッセージ

このコードのように最後の行を変更するとうまくいきます

  else
    raise e;

(1)->EConvertError -> エラーメッセージ

(2)-> EConvertError -> エラーメッセージ

しかし、「モジュール 'Test.exe' のアドレス 00405F04 でアクセス違反が発生しました。アドレス 00000000 を読み取りました。」メッセージの後

ベース例外と同じ例外タイプを発生させる方法

解決策はraise TObject(AcquireExceptionObject); です。//<- "E : で解決したい

type
  ECustomizedException = class(Exception);
 uses 
  fib,SysUtils,System


class procedure SystemEx.CustomizeException(E : Exception);
var
  s: String;
begin
  if E is EFIBInterBaseError then
  begin
    if Pos('unique',e.Message)>0 then
    begin
      s := 'Record';
      if Pos('CUSTOMMER_IDX1',e.Message)>0 then
        s:= 'Custommer';

      raise ECustomizedException.CreateFmt('%s is already exists.',[s]);
    end
    else
    if Pos('</CMSG>',e.Message)>0 then
    Begin
      raise ECustomizedException.CreateFmt('%s',
      [StrUtilsEx.GiveInTags(e.Message,'<CMSG>','</CMSG>')]
      );
    End
    else
      raise EFIBInterBaseError.CreateFmt('%s',[e.Message]);
  end
  else
    raise TObject(AcquireExceptionObject); //<- I would like to solve with "E : Exception" param
//    raise Exception.Create(e.Message);   //e;// e.Create(e.Message);// Exception.Create(E.Message);
End.
4

1 に答える 1

3

あなたが直面している問題は、例外がexceptブロックでキャッチされた場合、「終了」により、再び発生させた例外インスタンスが解放されることです。したがって、次の except ブロックは、既に解放された Exception インスタンスをキャッチします。ただし、例外インスタンスの所有者になる AcquireExceptionObject を呼び出すことで、これを防ぐことができます。

raise;(System.@RaiseAgain) を「使用できない」ため、同じ例外インスタンスをスローできますraise AcquireExceptionObject;

于 2012-06-14T13:25:18.817 に答える