IdHTTP异常导致分段错误

IdHTTP Exception Causes Segmentation Fault

我有 运行 下面的代码作为 Android 应用程序。 lHttp 向我创建的 WebService 发送请求,其中 IP (URL) 和端口由用户定义。但是,如果 Web 服务在 URL 中未激活,则应用程序会崩溃。调试时,它在尝试捕获异常时给了我以下错误。

raised exception class EIdHTTPProtocolException with message 'HTTP/1.1 500 Internal Server Error'.
raised exception class Segmentation fault (11).
raised exception class EAccessViolation with message 'Access violation at address B6FBD7CE, accessing address 000000A8'.

有人知道如何在不使应用程序崩溃的情况下捕获此异常吗?

  Path:= 'http://'+ Conf.IP + ':' + Conf.Port +'/services/MyWebService.dll/GetQuestions';

  lHTTP:= TIdHTTP.Create(nil);

  Stream:= TStringStream.Create;
  Stream.WriteString(Requisition);

  try
    Result := lHTTP.Post(Path, Stream);
  except
    on E:EIdException do
      Result:= E.Message;

    on E:EIdSocketError do
      Result:= E.Message;

    on E:EIdConnClosedGracefully do
      Result:= E.Message;

    on E:EIdHTTPProtocolException do
      Result:= E.Message;

    on E:Exception do
      Result:= E.Message;
  end;

  Stream.Free;

  FreeAndNil(lHTTP);

我不确定您实际要求的是什么:解决 500 ISE 或捕获异常,但我要:

Does someone know how to catch this exception whithout crashing the App?

答案:您可以创建一个全局异常处理程序。

1- 在表单的 "public declarations" 部分声明您的自定义异常处理程序。例如,如果您的表单名为 "Form1:"

{ Public declarations }
procedure MyExceptionHandler(Sender : TObject; E : Exception );

2 - 在 "implementation" 部分定义异常处理程序:

procedure TForm1.MyExceptionHandler(Sender : TObject; E : Exception );
begin

    if E.Message.Contains('HTTP/1.1 500 Internal Server Error') then
    begin
    // Do Something
    end;

    {
    // Default App Exception
    Application.ShowException( E );
    }

        end;

3 - 最后,将新创建的异常处理程序分配给应用程序的 OnException 事件。

procedure
  TForm1.FormCreate(Sender: TObject);
begin
  { begin new code }
  Application.OnException :=
    MyExceptionHandler;
  { end new code }
end;

看来你有两个问题。 500错误是服务器端的,它应该与客户端无关。 delphi 代码的问题是没有处理访问冲突。您应该尝试捕获异常以获取异常的更多详细信息。我没有其余的代码,因此很难测试。另外你在尝试什么样的请求?得到,post.....

lHTTP := TIdHTTP.Create; //Try with out NIL

  try 
    Result := lHTTP.Post(path, Stream);
    lHTTP.Destroy;  // Try destroying the TiDHTTP
  finally
    Stream.Free;
  except on e:Exception do
    ShowMessage (e.Message +' '+ Result); 
  end;

要查看每个异常,请在您的代码中添加显示消息以及每个异常的结果,以获取有关异常的更多信息。

ShowMessage (result); //if result is a string

EIdHTTPProtocolException表示服务器发送了错误响应。那应该是 Post() 提出的唯一例外。您的 except 块正在尝试处理它,但实际上不会看到它,因为您有一个较早的 EIdException 案例。所有 Indy 异常都源自 EIdException,并且 except 块匹配找到的第一个兼容案例。您的 EIdException 案例应该靠近 except 块的底部,而不是顶部:

  try
    Result := lHTTP.Post(Path, Stream);
  except
    on E:EIdHTTPProtocolException do
      Result:= E.Message;

    on E:EIdConnClosedGracefully do
      Result:= E.Message;

    on E:EIdSocketError do
      Result:= E.Message;

    on E:EIdException do
      Result:= E.Message;

    on E:Exception do
      Result:= E.Message;
  end;

可以简化为以下内容,因为所有异常都源自 Exception,并且您对特定异常类型没有做任何不同的事情:

  try
    Result := lHTTP.Post(Path, Stream);
  except
    on E:Exception do
      Result:= E.Message;
  end;

也就是说,您将必须调试您的应用程序并查看调用堆栈以找出实际发生段错误的位置。它很可能发生在您显示的代码之外。 Segfault(11) 等同于访问冲突。 EAccessViolation 似乎是由于某处访问了 nil 指针。