You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从脚本中的通用EDelphi异常获取Delphi端的异常类?

获取Delphi端抛出的真实异常类名

当调用脚本中的Delphi端函数时,异常会被包装为通用的EDelphi类,导致脚本端无法直接获取Delphi侧的真实异常类型(比如EOutOfMemory)。以下是两种可行的解决思路:

方案一:修改Delphi端,主动传递真实异常信息

这是最可靠的方式,在Delphi侧的函数实现中捕获异常,将真实异常的类名嵌入到EDelphi的异常信息中,或者通过自定义属性传递:

方式1:拼接异常消息

在Delphi端的函数里,捕获原始异常后,把真实类名和消息拼接成新的异常内容抛出:

procedure TMyDelphiClass.MyDelphiSideFunction;
begin
  try
    // 你的业务逻辑代码
  except
    on E: Exception do
    begin
      // 把真实异常类名嵌入消息
      raise EDelphi.CreateFmt('[%s] %s', [E.ClassName, E.Message]);
    end;
  end;
end;

脚本端解析消息提取类名:

Try
  MyDelphiSideFunction;
Except on E: EDelphi do
  begin
    if Pos('[', E.Message) > 0 then
    begin
      var RealClassName := Copy(E.Message, Pos('[', E.Message)+1, Pos(']', E.Message)-Pos('[', E.Message)-1);
      PrintLn('真实异常类名:' + RealClassName);
    end;
  end;
End;

方式2:给EDelphi添加自定义属性

如果脚本引擎允许扩展异常类,可以给EDelphi新增属性存储真实类名:

// Delphi端扩展EDelphi类
type
  EDelphi = class(Exception)
  private
    FRealExceptionClassName: string;
  public
    constructor CreateWithRealClass(const ARealClassName, AMsg: string);
    property RealExceptionClassName: string read FRealExceptionClassName;
  end;

constructor EDelphi.CreateWithRealClass(const ARealClassName, AMsg: string);
begin
  inherited Create(AMsg);
  FRealExceptionClassName := ARealClassName;
end;

// 函数中抛出带真实类名的异常
procedure TMyDelphiClass.MyDelphiSideFunction;
begin
  try
    // 业务逻辑
  except
    on E: Exception do
      raise EDelphi.CreateWithRealClass(E.ClassName, E.Message);
  end;
end;

脚本端直接访问属性:

Try
  MyDelphiSideFunction;
Except on E: EDelphi do
  PrintLn('真实异常类名:' + E.RealExceptionClassName);
End;

方案二:尝试访问EDelphi的内部接口

如果无法修改Delphi端代码,可以尝试利用EDelphi可能实现的内部接口来获取原始异常。你提到的Ijaddajadda可能是脚本引擎内部的接口(比如存储原始异常的接口),可以通过Supports函数尝试查询:

Try
  MyDelphiSideFunction;
Except on E: EDelphi do
  var
    OriginalEx: Exception;
  begin
    // 替换为实际的内部接口名,比如IOriginalException
    if Supports(E, IOriginalException, OriginalEx) then
      PrintLn('真实异常类名:' + OriginalEx.ClassName);
  end;
End;

如果不确定接口名,可以通过调试Delphi程序,查看EDelphi实例的内存结构,找到存储原始异常的字段,再通过脚本端的类型转换或反射机制读取。

内容的提问来源于stack exchange,提问作者LuWey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:15:07