jQuery Ajax-Fehlerbehandlung, benutzerdefinierte Ausnahmemeldungen anzeigen

727

Gibt es eine Möglichkeit, benutzerdefinierte Ausnahmemeldungen als Warnung in meiner jQuery AJAX-Fehlermeldung anzuzeigen?

Wenn ich beispielsweise über Struts by eine Ausnahme auf der Serverseite auslösenthrow new ApplicationException("User name already exists"); möchte, möchte ich diese Nachricht ('Benutzername existiert bereits') in der jQuery AJAX-Fehlermeldung abfangen.

jQuery("#save").click(function () {
  if (jQuery('#form').jVal()) {
    jQuery.ajax({
      type: "POST",
      url: "saveuser.do",
      dataType: "html",
      data: "userId=" + encodeURIComponent(trim(document.forms[0].userId.value)),
      success: function (response) {
        jQuery("#usergrid").trigger("reloadGrid");
        clear();
        alert("Details saved successfully!!!");
      },
      error: function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }
    });
  }
});

Bei der zweiten Warnung, bei der ich den ausgelösten Fehler alarmiere, wird undefinedder Statuscode 500 angezeigt.

Ich bin mir nicht sicher, wo ich falsch liege. Was kann ich tun, um dieses Problem zu beheben?

Roman C.
quelle

Antworten:

357

Stellen Sie sicher, dass Sie eine Response.StatusCodeandere Einstellung als 200 festlegen. Schreiben Sie die Nachricht Ihrer Ausnahme mit Response.Writeund verwenden Sie dann ...

xhr.responseText

..in Ihrem Javascript.

Sprintstar
quelle
9
Dies ist nach zweieinhalb Jahren immer noch der richtige Weg ... :) Ich bin ein wenig weiter gegangen und habe tatsächlich mein eigenes Fehler-JSON-Objekt zurückgegeben, das einzelne oder mehrere Fehler verarbeiten kann, was für die serverseitige Formularüberprüfung recht gut ist.
AlexCode
@ Wilson Es war wie in den anderen hoch bewerteten Antworten hier gezeigt.
Sprintstar
3
Bin jetzt im Jahr 2014. JSON dominierte Ära. Also benutze ich xhr.responseJSON. : D
Ravi
5
xhr.responseJSON wird nur festgelegt, wenn Sie sicherstellen, dass der Metatyp festgelegt ist (z. B. "Inhaltstyp: application / json"). Das ist ein Problem, auf das ich gerade gestoßen bin. responseText wurde gesetzt - responseJSON nicht.
Igor
217

Regler:

public class ClientErrorHandler : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        var response = filterContext.RequestContext.HttpContext.Response;
        response.Write(filterContext.Exception.Message);
        response.ContentType = MediaTypeNames.Text.Plain;
        filterContext.ExceptionHandled = true;
    }
}

[ClientErrorHandler]
public class SomeController : Controller
{
    [HttpPost]
    public ActionResult SomeAction()
    {
        throw new Exception("Error message");
    }
}

Skript anzeigen:

$.ajax({
    type: "post", url: "/SomeController/SomeAction",
    success: function (data, text) {
        //...
    },
    error: function (request, status, error) {
        alert(request.responseText);
    }
});
AlexMAS
quelle
13
Dies ist keine "richtige" Antwort auf die Frage, aber es zeigt mit Sicherheit eine übergeordnete Lösung für das Problem ... Schön!
Ryan Anderson
3
Ich mache etwas ähnliches. Es funktioniert gut, wenn alles auf der Entwicklungsbox erledigt ist. Wenn ich versuche, eine Verbindung von einer anderen Box im Netzwerk herzustellen, enthält die xhr.responseText die allgemeine Fehlerseite HTML und nicht meine benutzerdefinierte Nachricht, siehe stackoverflow.com/questions/3882752/…
jamiebarrow
6
Ich glaube, Sie sollten auch response.StatusCode = 500 hinzufügen ; Zeile zur OnException-Methode.
Alexander Prokofyev
4
Ich habe dies angepasst - da ich den 500-Statuscode haben wollte, aber die Ausnahmemeldung in der Statusbeschreibung haben sollte (anstatt "Interner Serverfehler") - response.StatusCode = (int)HttpStatusCode.InternalServerError;undresponse.StatusDescription = filterContext.Exception.Message;
Kram
4
Wenn Sie IIS7 oder höher verwenden, müssen Sie möglicherweise Folgendes hinzufügen: response.TrySkipIisCustomErrors = true;
James Gaunt
97

ServerSide:

     doPost(HttpServletRequest request, HttpServletResponse response){ 
            try{ //logic
            }catch(ApplicationException exception){ 
               response.setStatus(400);
               response.getWriter().write(exception.getMessage());
               //just added semicolon to end of line

           }
 }

ClientSide:

 jQuery.ajax({// just showing error property
           error: function(jqXHR,error, errorThrown) {  
               if(jqXHR.status&&jqXHR.status==400){
                    alert(jqXHR.responseText); 
               }else{
                   alert("Something went wrong");
               }
          }
    }); 

Allgemeine Ajax-Fehlerbehandlung

Wenn ich eine allgemeine Fehlerbehandlung für alle Ajax-Anforderungen durchführen muss. Ich werde den AjaxError-Handler setzen und den Fehler in einem Div mit dem Namen errorcontainer oben im HTML-Inhalt anzeigen.

$("div#errorcontainer")
    .ajaxError(
        function(e, x, settings, exception) {
            var message;
            var statusErrorMap = {
                '400' : "Server understood the request, but request content was invalid.",
                '401' : "Unauthorized access.",
                '403' : "Forbidden resource can't be accessed.",
                '500' : "Internal server error.",
                '503' : "Service unavailable."
            };
            if (x.status) {
                message =statusErrorMap[x.status];
                                if(!message){
                                      message="Unknown Error \n.";
                                  }
            }else if(exception=='parsererror'){
                message="Error.\nParsing JSON Request failed.";
            }else if(exception=='timeout'){
                message="Request Time out.";
            }else if(exception=='abort'){
                message="Request was aborted by the server";
            }else {
                message="Unknown Error \n.";
            }
            $(this).css("display","inline");
            $(this).html(message);
                 });
Sanjeev Kumar Dangi
quelle
81

Sie müssen das responseTextin JSON konvertieren . Verwenden von JQuery:

jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);
Sydney
quelle
5
+1, weil dies derzeit die einzige RICHTIGE Antwort auf diese Frage ist! Sie können "jsonValue.Message" aufrufen, um die Ausnahmemeldung abzurufen.
Captain Sensible
2
Tatsächlich ist es nicht die richtige Antwort, da die Frage nicht nach JSON fragt und die Beispielanforderung speziell nach HTML als Antwort fragt.
SingleShot
+1 Richtig. Hinweis: Es ist üblich, ein JSON-codiertes Objekt über jqXHR.responseText (Zeichenfolge) zu senden. Anschließend können Sie das jsonValue-Objekt nach Bedarf verwenden. Verwenden Sie die Firebug-Konsole, um die Antwort mithilfe von console.log (jsonValue) zu überprüfen.
JJWDesign
Dies gibt mir 'Uncaught SyntaxError: Unexpected number'
Ben Racicot
1
Das analysierte JSON-Objekt wird über die responseJSON-Eigenschaft des jqXHR-Objekts verfügbar gemacht. Es ist also nicht erforderlich, die responseText-Eigenschaft zu analysieren. Sie können einfach tun: console.log (jqXHR.responseJSON.Message)
Eric D'Souza
37

Wenn Sie asp.net aufrufen, wird der Titel der Fehlermeldung zurückgegeben:

Ich habe nicht alle formatErrorMessage selbst geschrieben, aber ich finde es sehr nützlich.

function formatErrorMessage(jqXHR, exception) {

    if (jqXHR.status === 0) {
        return ('Not connected.\nPlease verify your network connection.');
    } else if (jqXHR.status == 404) {
        return ('The requested page not found. [404]');
    } else if (jqXHR.status == 500) {
        return ('Internal Server Error [500].');
    } else if (exception === 'parsererror') {
        return ('Requested JSON parse failed.');
    } else if (exception === 'timeout') {
        return ('Time out error.');
    } else if (exception === 'abort') {
        return ('Ajax request aborted.');
    } else {
        return ('Uncaught Error.\n' + jqXHR.responseText);
    }
}


var jqxhr = $.post(addresshere, function() {
  alert("success");
})
.done(function() { alert("second success"); })
.fail(function(xhr, err) { 

    var responseTitle= $(xhr.responseText).filter('title').get(0);
    alert($(responseTitle).text() + "\n" + formatErrorMessage(xhr, err) ); 
})
Sam Jones
quelle
22

Dies ist, was ich getan habe und es funktioniert bisher in einer MVC 5-Anwendung.

Der Rückgabetyp des Controllers ist ContentResult.

public ContentResult DoSomething()
{
    if(somethingIsTrue)
    {
        Response.StatusCode = 500 //Anything other than 2XX HTTP status codes should work
        Response.Write("My Message");
        return new ContentResult();
    }

    //Do something in here//
    string json = "whatever json goes here";

    return new ContentResult{Content = json, ContentType = "application/json"};
}

Und auf der Clientseite sieht die Ajax-Funktion so aus

$.ajax({
    type: "POST",
    url: URL,
    data: DATA,
    dataType: "json",
    success: function (json) {
        //Do something with the returned json object.
    },
    error: function (xhr, status, errorThrown) {
        //Here the status code can be retrieved like;
        xhr.status;

        //The message added to Response object in Controller can be retrieved as following.
        xhr.responseText;
    }
});
Cengiz Araz
quelle
20

Wenn jemand wie 2016 hier ist, um die Antwort zu erhalten, verwenden Sie diese .fail()für die Fehlerbehandlung, da .error()sie ab jQuery 3.0 veraltet ist

$.ajax( "example.php" )
  .done(function() {
    alert( "success" );
  })
  .fail(function(jqXHR, textStatus, errorThrown) {
    //handle error here
  })

Ich hoffe, es hilft

Lerner
quelle
2
jqXHR.error()ist in jQuery 3.0 veraltet (tatsächlich entfernt), aber die errorund successRückrufe auf $.ajax()sind meines Wissens nicht veraltet.
Neil Conway
16

Eine allgemeine / wiederverwendbare Lösung

Diese Antwort dient als zukünftige Referenz für alle, die auf dieses Problem stoßen. Die Lösung besteht aus zwei Dingen:

  1. Benutzerdefinierte Ausnahme ModelStateException , die ausgelöst wird, wenn die Validierung auf dem Server fehlschlägt (der Modellstatus meldet Validierungsfehler, wenn wir Datenanmerkungen verwenden und stark typisierte Controller-Aktionsparameter verwenden).
  2. Fehlerfilter für benutzerdefinierte Controller-Aktion HandleModelStateExceptionAttribute , der benutzerdefinierte Ausnahmen abfängt und den HTTP-Fehlerstatus mit Modellstatusfehler im Hauptteil zurückgibt

Dies bietet die optimale Infrastruktur für jQuery Ajax-Aufrufe, um ihr volles Potenzial mit successund errorHandlern auszuschöpfen .

Client-seitiger Code

$.ajax({
    type: "POST",
    url: "some/url",
    success: function(data, status, xhr) {
        // handle success
    },
    error: function(xhr, status, error) {
        // handle error
    }
});

Serverseitiger Code

[HandleModelStateException]
public ActionResult Create(User user)
{
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }

    // create new user because validation was successful
}

Das gesamte Problem wird in diesem Blog-Beitrag beschrieben, in dem Sie den gesamten Code finden, um dies in Ihrer Anwendung auszuführen.

Robert Koritnik
quelle
14

Ich fand das nett, weil ich die vom Server gesendete Nachricht analysieren und dem Benutzer eine freundliche Nachricht ohne Stacktrace anzeigen konnte ...

error: function (response) {
      var r = jQuery.parseJSON(response.responseText);
      alert("Message: " + r.Message);
      alert("StackTrace: " + r.StackTrace);
      alert("ExceptionType: " + r.ExceptionType);
}
verrückter Diamant
quelle
11

 error:function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }
Bei Codefehler Ajax-Anforderung für Fangfehler Verbindung zwischen Client und Server herstellen, wenn die Fehlermeldung Ihrer Anwendung im Erfolgsbereich angezeigt werden soll

sowie

success: function(data){
   //   data is object  send  form server 
   //   property of data 
   //   status  type boolean 
   //   msg     type string
   //   result  type string
  if(data.status){ // true  not error 
         $('#api_text').val(data.result);
  }
  else 
  {
      $('#error_text').val(data.msg);
  }

}

Wara Haii
quelle
7

Dies wird wahrscheinlich dadurch verursacht, dass die JSON-Feldnamen keine Anführungszeichen haben.

Ändern Sie die JSON-Struktur von:

{welcome:"Welcome"}

zu:

{"welcome":"Welcome"}
Kerl
quelle
1
Dies sollte keine Rolle spielen, es sei denn, der Schlüssel ist ein reserviertes Wort in JS. Ich sehe das hier nicht als Problem.
John Gibb
1
JSON.stringify ({Willkommen: "Willkommen"}) -> {"Willkommen": "Willkommen"}
Thulasiram
5

Ich glaube, der Ajax-Antworthandler verwendet den HTTP-Statuscode, um zu überprüfen, ob ein Fehler aufgetreten ist.

Wenn Sie also nur eine Java-Ausnahme für Ihren serverseitigen Code auslösen, die HTTP-Antwort jedoch keinen 500-Statuscode jQuery (oder in diesem Fall wahrscheinlich XMLHttpRequest) hat Objekt) einfach davon aus, dass alles in Ordnung war.

Ich sage das, weil ich in ASP.NET ein ähnliches Problem hatte, bei dem ich so etwas wie eine ArgumentException ausgelöst habe ("Weiß nicht, was ich tun soll ..."), aber der Fehlerhandler nicht ausgelöst hat.

Ich habe dann Response.StatusCodeentweder 500 oder 200 eingestellt, ob ich einen Fehler hatte oder nicht.

Vitor Silva
quelle
5

jQuery.parseJSON ist nützlich für Erfolg und Fehler.

$.ajax({
    url: "controller/action",
    type: 'POST',
    success: function (data, textStatus, jqXHR) {
        var obj = jQuery.parseJSON(jqXHR.responseText);
        notify(data.toString());
        notify(textStatus.toString());
    },
    error: function (data, textStatus, jqXHR) { notify(textStatus); }
});
Nuri YILMAZ
quelle
5

Sie haben ein JSON-Objekt der ausgelösten Ausnahme im xhr-Objekt. Benutz einfach

alert(xhr.responseJSON.Message);

Das JSON-Objekt stellt zwei weitere Eigenschaften bereit: 'ExceptionType' und 'StackTrace'

Edika
quelle
5

Diese Funktion generiert grundsätzlich eindeutige zufällige API-Schlüssel. Falls dies nicht der Fall ist, wird ein Popup-Dialogfeld mit einer Fehlermeldung angezeigt

In Ansichtsseite:

<div class="form-group required">
    <label class="col-sm-2 control-label" for="input-storename"><?php echo $entry_storename; ?></label>
    <div class="col-sm-6">
        <input type="text" class="apivalue"  id="api_text" readonly name="API" value="<?php echo strtoupper(substr(md5(rand().microtime()), 0, 12)); ?>" class="form-control" />                                                                    
        <button type="button" class="changeKey1" value="Refresh">Re-Generate</button>
    </div>
</div>

<script>
$(document).ready(function(){
    $('.changeKey1').click(function(){
          debugger;
        $.ajax({
                url  :"index.php?route=account/apiaccess/regenerate",
                type :'POST',
                dataType: "json",
                async:false,
                contentType: "application/json; charset=utf-8",
                success: function(data){
                  var result =  data.sync_id.toUpperCase();
                        if(result){
                          $('#api_text').val(result);
                        }
                  debugger;
                  },
                error: function(xhr, ajaxOptions, thrownError) {
                  alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
                }

        });
    });
  });
</script>

Vom Controller:

public function regenerate(){
    $json = array();
    $api_key = substr(md5(rand(0,100).microtime()), 0, 12);
    $json['sync_id'] = $api_key; 
    $json['message'] = 'Successfully API Generated';
    $this->response->addHeader('Content-Type: application/json');
    $this->response->setOutput(json_encode($json));
}

Der optionale Rückrufparameter gibt eine Rückruffunktion an, die ausgeführt werden soll, wenn die load () -Methode abgeschlossen ist. Die Rückruffunktion kann verschiedene Parameter haben:

Typ: Funktion (jqXHR jqXHR, String textStatus, String errorThrown)

Eine Funktion, die aufgerufen werden soll, wenn die Anforderung fehlschlägt. Die Funktion erhält drei Argumente: Das Objekt jqXHR (in jQuery 1.4.x, XMLHttpRequest), eine Zeichenfolge, die den aufgetretenen Fehlertyp beschreibt, und ein optionales Ausnahmeobjekt, falls eines aufgetreten ist. Mögliche Werte für das zweite Argument (neben null) sind "timeout", "error", "abort" und "parsererror". Wenn ein HTTP-Fehler auftritt, empfängt errorThrown den Textteil des HTTP-Status, z. B. "Nicht gefunden" oder "Interner Serverfehler". Ab jQuery 1.5 kann die Fehlereinstellung eine Reihe von Funktionen akzeptieren. Jede Funktion wird nacheinander aufgerufen. Hinweis: Dieser Handler wird nicht für domänenübergreifende Skript- und domänenübergreifende JSONP-Anforderungen aufgerufen.

Nɪsʜᴀɴᴛʜ ॐ
quelle
4
$("#save").click(function(){
    $("#save").ajaxError(function(event,xhr,settings,error){
        $(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
    });
});
ibrahim ozboluk
quelle
3

Wirf eine neue Ausnahme auf den Server mit:

Response.StatusCode = 500

Response.StatusDescription = ex.Message ()

Ich glaube, dass die StatusDescription an den Ajax-Aufruf zurückgegeben wird ...

Beispiel:

        Try

            Dim file As String = Request.QueryString("file")

            If String.IsNullOrEmpty(file) Then Throw New Exception("File does not exist")

            Dim sTmpFolder As String = "Temp\" & Session.SessionID.ToString()

            sTmpFolder = IO.Path.Combine(Request.PhysicalApplicationPath(), sTmpFolder)

            file = IO.Path.Combine(sTmpFolder, file)

            If IO.File.Exists(file) Then

                IO.File.Delete(file)

            End If

        Catch ex As Exception

            Response.StatusCode = 500

            Response.StatusDescription = ex.Message()

        End Try
Steffan
quelle
2

Obwohl es viele Jahre her ist, dass diese Frage gestellt wird, finde ich immer noch nicht xhr.responseTextdie Antwort, nach der ich gesucht habe. Es gab mir einen String im folgenden Format zurück:

"{"error":true,"message":"The user name or password is incorrect"}"

was ich den Benutzern definitiv nicht zeigen möchte. Was ich gesucht habe, ist ungefähr so:

alert(xhr.responseJSON.message);

xhr.responseJSON.message gibt mir die genaue Nachricht vom Json-Objekt, die den Benutzern angezeigt werden kann.

Saket
quelle
1
$("#fmlogin").submit(function(){
   $("#fmlogin").ajaxError(function(event,xhr,settings,error){
       $("#loading").fadeOut('fast');       
       $("#showdata").fadeIn('slow');   
       $("#showdata").html('Error please, try again later or reload the Page. Reason: ' + xhr.status);
       setTimeout(function() {$("#showdata").fadeOut({"opacity":"0"})} , 5500 + 1000); // delays 1 sec after the previous one
    });
});

Wenn es ein Formular gibt, senden Sie es mit validate

Verwenden Sie einfach den Rest des Codes

$("#fmlogin").validate({...

... ... });

Monzur
quelle
0

Zuerst müssen wir <serviceDebug includeExceptionDetailInFaults = "True" /> in web.config setzen:

<serviceBehaviors> 
 <behavior name=""> 
  <serviceMetadata httpGetEnabled="true" /> 
    **<serviceDebug includeExceptionDetailInFaults="true" />** 
 </behavior> 
</serviceBehaviors>

Darüber hinaus müssen Sie auf jquery-Ebene im Fehlerteil eine Fehlerantwort analysieren, die Ausnahmen enthält wie:

.error(function (response, q, t) { 
  var r = jQuery.parseJSON(response.responseText); 
}); 

Mit r.Message können Sie dann den Ausnahmetext tatsächlich anzeigen.

Überprüfen Sie den vollständigen Code: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

Avinash
quelle