简体   繁体   English

IdHTTP异常导致分段错误

[英]IdHTTP Exception Causes Segmentation Fault

I have run the code below as an Android App. 我已将以下代码作为Android应用程序运行。 The lHttp sends an request to a WebService that i made, where the IP (URL) and Port are defined by the user. lHttp向我发出的WebService发送请求,其中IP(URL)和端口由用户定义。 However, if the webservice is not active in that URL the App is crashed. 但是,如果Web服务在该URL中未处于活动状态,则应用程序将崩溃。 While debugging, it gives me the following errors while trying to catch an exception. 在调试时,它在尝试捕获异常时给出了以下错误。

raised exception class EIdHTTPProtocolException with message 'HTTP/1.1 500 Internal Server Error'. 引发了异常类EIdHTTPProtocolException,消息“HTTP / 1.1 500内部服务器错误”。
raised exception class Segmentation fault (11). 引发异常类分段错误(11)。
raised exception class EAccessViolation with message 'Access violation at address B6FBD7CE, accessing address 000000A8'. 引发异常类EAccessViolation,并显示消息'地址为B6FBD7CE的访问冲突,访问地址000000A8'。

Does someone know how to catch this exception whithout crashing the App? 有人知道如何在不破坏应用程序的情况下捕获此异常吗?

  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);

I'm not sure of what you are actually asking for: solving 500 ISE or catching the exception, but I'm going with: 我不确定你实际要求的是什么:解决500 ISE或捕获异常,但我要去:

Does someone know how to catch this exception whithout crashing the App? 有人知道如何在不破坏应用程序的情况下捕获此异常吗?

Answer: You can create a global exception handler. 答:您可以创建一个全局异常处理程序。

1- Declare your custom exception handler in your form's "public declarations" section. 1-在表单的“公共声明”部分中声明自定义异常处理程序。 For example, if your form is named "Form1:" 例如,如果您的表单名为“Form1:”

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

2 - Define your exception handler in the "implementation" section: 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 - Finally, assign the newly created exception handler to your application's OnException event. 3 - 最后,将新创建的异常处理程序分配给应用程序的OnException事件。

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

It seems that you have two problems. 看来你有两个问题。 The 500 error is a server side an it should have nothing to do with the client side. 500错误是服务器端,它应该与客户端无关。 The problem with the delphi code is that is not handling the access violation. delphi代码的问题是不处理访问冲突。 You should try to do a catch exception to get more details of the exception. 您应该尝试执行catch异常以获取异常的更多详细信息。 I don't have the rest of the code so is hard to test. 我没有剩下的代码所以很难测试。 Also what kind of request are you trying? 你还在尝试什么样的要求? get, 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;

to see each exception add a showmessage plus the result on every exception on your code to get more info on the exceptions. 要查看每个异常,请在代码的每个异常上添加showmessage和结果​​,以获取有关异常的更多信息。

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

EIdHTTPProtocolException means the server sent an error response. EIdHTTPProtocolException表示服务器发送了错误响应。 That should be the only exception being raised by Post() . 这应该是Post()提出的唯一例外。 Your except block is trying to handle it, but won't actually see it since you have an earlier case for EIdException . 你的except块试图处理它,但实际上看不到它,因为你有一个早期的EIdException All Indy exceptions derive from EIdException , and an except block matches on the first compatible case found. 所有Indy异常都来自EIdException ,并且在发现的第一个兼容案例中, except块匹配。 Your EIdException case should be near the bottom of the except block, not the top: 您的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;

Which can be simplified to the following, as all exceptions derive from Exception , and you are not doing anything different for specific exception types: 这可以简化为以下内容,因为所有异常都派生自Exception ,并且您没有针对特定异常类型执行任何不同的操作:

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

That being said, you will have to debug your app and look at the call stack to figure out where the segfault is actually occuring. 话虽这么说,你将不得不调试你的应用程序,并查看调用堆栈,以找出segfault实际发生的位置。 It is likely occuring outside of the code you have shown. 它可能出现在您显示的代码之外。 Segfault(11) is equivalent to an access violation. Segfault(11)相当于访问冲突。 The EAccessViolation appears to be due to a nil pointer being accessed somewhere. EAccessViolation似乎是由于在某处访问了nil指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM