首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi重新引发异常(作为参数在过程中传递)

Delphi重新引发异常(作为参数在过程中传递)
EN

Stack Overflow用户
提问于 2012-06-14 12:36:01
回答 1查看 4.1K关注 0票数 4

这是重新引发异常并运行良好的示例。

代码语言:javascript
复制
  try
    raise Exception.Create('Exception msg');
  except
    on E: Exception do
    begin
      if not(e is EConvertError) then
        raise; // re-raise exception
    end;
  end;

这是我的Custemize方法

代码语言:javascript
复制
//    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;

代码语言:javascript
复制
  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)->Exception ->错误消息

当我像这段代码一样修改最后一行时,效果很好。

代码语言:javascript
复制
  else
    raise e;

(1)->EConvertError ->错误消息

(2)->EConvertError ->错误消息

但我得到的是“模块'Test.exe‘中地址00405F04的访问违规。请阅读地址00000000。”事后消息

如何引发与基本异常相同的异常类型

解决方案是“TObject(AcquireExceptionObject);//<- -我想用"E”来解决:

代码语言:javascript
复制
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.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-14 13:25:18

您面临的问题是,如果一个异常被捕获在一个end块中,那么"end“将释放您刚刚引发的异常实例。因此,下一个next块将捕获已经释放的异常实例。但是,您可以通过调用AcquireExceptionObject来防止这种情况,这使您成为异常实例的所有者。

因为您“不能”使用raise; (System.@RaiseA增益),所以您可以使用raise AcquireExceptionObject;抛出相同的异常实例

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11033177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档