【问题标题】:Indy 10 raising an unwanted exceptionIndy 10 引发了一个不需要的异常
【发布时间】:2015-08-31 16:56:22
【问题描述】:

我有一个在 delphi XE 中开发的客户端/服务器应用程序,它使用 TIdTcpClient (Indy10) 相互通信。 大多数时候一切正常,唯一的问题是当我杀死服务器端时,客户端引发异常,以某种方式一直引发到用户,它首先显示我的自定义异常:

然后在空白处显示一个错误对话框,如下所示:

这是应该覆盖原始异常的代码,我创建的对话框显示和另一个对话框(上图)紧随其后。

constructor EtvdNTierTcpException.Create(const AException: Exception);
const
 error = 'error message';

var
  AIdSocketError: EIdSocketError;
  sMessage, sConnectionPoint: string;
begin
  if AException is EIdSocketError then
  begin
    AIdSocketError := AException as EIdSocketError;
    if StvdDefaultSession.tvdConnectionPoint = cpSqlProxy then
      sConnectionPoint := FtvdNTierSqlProxy
    else
      sConnectionPoint := FtvdNTierSqlServer;
    case AIdSocketError.LastError of
      // 10054: Connection reset by peer
      10054: self.Message := ExtractFileName(application.exename) + error +  DateToStr(Now) + ' ' + TimeToStr(Now) + ' (' + AIdSocketError.ClassName + ')' + 'Connection for dataset fail at(10054)';
      // 10061: Connection refused
      10061: self.Message := ExtractFileName(application.exename) + error +  DateToStr(Now) + ' ' + TimeToStr(Now) + ' (' + AIdSocketError.ClassName + ')' + 'Connection for dataset fail at(10061)';
      else
        self.Message := error +  DateToStr(Now) + ' ' + TimeToStr(Now) + ' (' + AIdSocketError.ClassName + ')' + 'Connection for dataset fail at('+IntToStr(AIdSocketError.LastError)+')';
    end;
  end;
  inherited;
end;

我尝试使用CheckForGraceFulDisconnect(false);,但它没有任何区别,关于如何阻止 Indy 显示此错误的任何想法?

这就是引发上述异常的方式:

function TtvdNTierDataSet.tvdStmtExecute(const AStmt: string): Boolean;
begin
  try
      tvdStmtExecute := False;
      // check we are still connected to the server
      if tvdSession.tvdConnect then
      begin
        tvdStmtExecute := True;
        // write the SQL Statement to the server
        tvdWriteOutput;
      end;
  except
    on E: Exception do
    begin
      // re-raise the exception
      raise EtvdNTierTcpException.Create(E);
    end;
  end;
end;

【问题讨论】:

  • 您不应覆盖原始代码。你在主线程中使用 TCPClient 吗?您应该使用单独的线程。最后,您是否尝试过 TCPClient 操作的 try/except ?您应该捕获任何异常。
  • 您没有显示从哪里调用 EtvdNTierTcpException.Create(),或者在什么代码中引发了原始异常。在下一次访问底层套接字之前,Indy 不会在断开连接时引发异常。而修改原始异常通常是错误的做法。假设EtvdNTierTcpExceptionException 的后代,请考虑使用捕获原始异常的try/except 并使用Exception.RaiseOuterException() 引发您自己的异常,该异常将原始异常捕获为其InnerException 而无需修改它。
  • @Icaro:那你为什么要修改原来的EIdSocketError?引发您自己的异常只会丢弃先前的异常,因为您正在捕获它(或者您是吗?您仍然没有显示引发异常的实际代码)。
  • @Icaro:您的异常构造函数正在修改原始 EIdSocketError 异常的 Message 属性,而不是您自己异常的 Message 属性。留下原件。从中读取,不要修改它。您的异常 Message 为空白,这就是用户看到空白消息框的原因。
  • @Icaro:如果您希望异常处理程序有机会看到触发您的异常的原始异常:on E: Exception do begin Exception.RaiseOuterException(EtvdNTierTcpException.Create(E)); end;,您可以选择将原始异常捕获到异常的InnerException 属性中。跨度>

标签: delphi tcp delphi-xe indy indy10


【解决方案1】:

如果异常不是 EIdSocketError 类型,则会得到一个空的异常对话框。

if AException is EIdSocketError then

【讨论】:

  • 这不是真的,如果异常不是 EIdSocketError 类型,我会得到原始的异常对话框,我已经测试过了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 2012-02-04
  • 1970-01-01
  • 2011-12-22
  • 2022-11-09
  • 2011-05-08
  • 2019-04-27
相关资源
最近更新 更多