IdHTTP异常导致分段错误

时间:2016-04-29 13:59:40

标签: android delphi exception firemonkey idhttp

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

引发异常类EIdHTTPProtocolException并显示消息' HTTP / 1.1 500内部服务器错误'。
引发异常类Segmentation fault(11)。
引发异常类EAccessViolation,并在地址B6FBD7CE处发出访问冲突,访问地址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);

3 个答案:

答案 0 :(得分:0)

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

  

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

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

1-在表单的“公共声明”部分中声明自定义异常处理程序。例如,如果您的表单名为“Form1:”

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

2 - 在“实施”部分中定义您的异常处理程序:

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;

答案 1 :(得分:0)

看来你有两个问题。 500错误是服务器端,它应该与客户端无关。 delphi代码的问题是不处理访问冲突。您应该尝试执行catch异常以获取异常的更多详细信息。我没有剩下的代码所以很难测试。你还在尝试什么样的要求?得到,发布....

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和结果​​,以获取有关异常的更多信息。

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

答案 2 :(得分:0)

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实际发生的位置。它可能出现在您显示的代码之外。 Segfault(11)相当于访问冲突。 EAccessViolation似乎是由于在某处访问了nil指针。