2016-04-29 18 views
1

Ich habe den folgenden Code als eine Android App ausgeführt. Das lHttp sendet eine Anfrage an einen WebService, den ich gemacht habe, wo die IP (URL) und der Port vom Benutzer definiert wurden. Wenn der Webservice in dieser URL nicht aktiv ist, ist die App jedoch abgestürzt. Während des Debuggens gibt es die folgenden Fehler beim Versuch, eine Ausnahme abzufangen.IDHTTP Exception verursacht Segmentation Fault

ausgelöst Ausnahmeklasse EIdHTTPProtocolException mit der Nachricht 'HTTP/1.1 500 Internal Server Error'.
ausgelöste Ausnahmeklasse Segmentierungsfehler (11).
ausgelöst Exception Klasse EAccessViolation mit der Meldung 'Zugriff auf die Adresse B6FBD7CE, Zugriff auf Adresse 000000A8'.

Kann jemand diese Ausnahme fangen, ohne die App zu stürzen?

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

Welcher der fünf Ausnahme-Handler fängt tatsächlich die Ausnahme? Es ist möglich, dass die serverseitige MyWebService.dll einen Fehler hatte, und die HTTP-Antwort nur die Fehlermeldung an Ihre Client-App – mjn

+0

"HTTP/1.1 500 Internal Server Error" sendet, bedeutet, dass Sie eine falsche Anfrage an den Server senden oder Es ist einfach ein Problem auf der Serverseite. – Machado

Antwort

0

Ich bin nicht sicher, was Sie wirklich fordern sind: 500 ISE lösen oder die Ausnahme abfangen, aber ich werde mit:

jemand Kennt wie diese Ausnahme fangen whithout die App abstürzen?

Antwort: Sie können einen globalen Ausnahmebehandler erstellen.

1- Deklarieren Sie Ihren benutzerdefinierten Ausnahmebehandler im Abschnitt "Öffentliche Deklarationen" Ihres Formulars. Zum Beispiel wird, wenn das Formular "Form1" genannt

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

2 - Definieren Sie Ihre Exception-Handler in der "Umsetzung" Abschnitt:

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 - Schließlich ordnen Sie die neu erstellte Ausnahmebehandler das OnException-Ereignis Ihrer Anwendung.

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

Es scheint, dass Sie zwei Probleme haben. Der Fehler 500 ist eine Server-Seite und sollte nichts mit der Client-Seite zu tun haben. Das Problem mit dem Delphi-Code ist, dass die Zugriffsverletzung nicht behandelt wird. Sie sollten versuchen, eine Catch-Ausnahme durchzuführen, um weitere Details der Ausnahme zu erhalten. Ich habe den Rest des Codes nicht, also ist es schwer zu testen. Auch welche Art von Anfrage versuchen Sie? erhalten, 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; 

jede Ausnahme zu sehen, eine Showmessage und das Ergebnis auf jeder Ausnahme auf Ihrem Code hinzufügen, um weitere Informationen zu den Ausnahmen zu bekommen.

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

uhhm, welche Syntax und Parameter habe ich erfunden? Dies sind Delphi-Syntax und -Parameter. Ich versuche, die Zugriffsverletzung zu beheben. – Deleted

+0

Der erste Parameter zum Erstellen ist nicht optional. Du verpasst einen "Versuch". Ich bin mit anderen Worten, du machst Stiche in der Dunkelheit, die unmöglich kompilieren können. Außerdem, wo tritt die Zugriffsverletzung auf und welche Ihrer Änderungen behebt sie? Schließlich empfehlen wir nicht, 'Destroy' anstelle von' Free' zu ​​nennen, und empfehle nicht, es an der falschen Stelle aufzurufen. –

+0

Wenn 'lHttp.Post() 'fehlschlägt, wird' lHttp.Destroy()' übersprungen. Es sollte allein sein "versuchen/endlich". –

0

EIdHTTPProtocolException bedeutet, dass der Server eine Fehlerantwort gesendet hat. Dies sollte die einzige Ausnahme sein, die von Post() ausgelöst wird. Ihr except Block versucht, damit umzugehen, aber wird es nicht wirklich sehen, da Sie einen früheren Fall für EIdException haben. Alle Indy-Ausnahmen stammen von EIdException, und ein except Block entspricht dem ersten gefundenen kompatiblen Fall.Ihr EIdException Fall in der Nähe der Unterseite des except Block sein sollte, nicht die Spitze:

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; 

Welche der folgenden vereinfacht werden kann, da alle Ausnahmen von Exception ableiten, und Sie sind nicht etwas anderes für bestimmte Ausnahmetypen zu tun :

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

Dass gesagt wird, werden Sie Ihre App und auf den Call-Stack aussehen debuggen müssen die segfault um herauszufinden, wo tatsächlich auftritt. Es tritt wahrscheinlich außerhalb des Codes auf, den Sie angezeigt haben. Segfault (11) entspricht einer Zugriffsverletzung. Die EAccessViolation scheint auf einen Null-Zeiger zurückzuführen zu sein, auf den irgendwo zugegriffen wird.