Question Gestion des erreurs jQuery Ajax, afficher les messages d'exception personnalisés


Existe-t-il un moyen de montrer des messages d'exception personnalisés comme une alerte dans mon message d'erreur jQuery AJAX?

Par exemple, si je veux lancer une exception du côté serveur via Struts par throw new ApplicationException("User name already exists");, Je veux attraper ce message ('nom d'utilisateur existe déjà') dans le message d'erreur jQuery AJAX.

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

Sur la deuxième alerte, où j'alerte l'erreur lancée, je reçois undefined et le code d'état est 500.

Je ne suis pas sûr d'où je vais mal. Que puis-je faire pour résoudre ce problème?


645
2017-12-18 12:06


origine


Réponses:


Assurez-vous que vous définissez Response.StatusCode à quelque chose d'autre que 200. Écrivez le message de votre exception en utilisant Response.Write, puis utilisez ...

xhr.responseText

..dans votre javascript.


321
2018-01-16 14:25



Manette:

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

Afficher le script:

$.ajax({
    type: "post", url: "/SomeController/SomeAction",
    success: function (data, text) {
        //...
    },
    error: function (request, status, error) {
        alert(request.responseText);
    }
});

193
2018-05-10 07:16



Du côté serveur: 

     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

           }
 }

Côté client:

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

Gestion des erreurs Ajax génériques

Si j'ai besoin de faire un traitement d'erreur générique pour toutes les demandes ajax. Je vais définir le gestionnaire ajaxError et afficher l'erreur sur un div nommé errorcontainer en haut du contenu html.

$("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);
                 });

90
2018-02-25 17:09



Vous devez convertir le responseText à JSON. En utilisant JQuery:

jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);

72
2018-04-13 15:49



Si vous appelez asp.net, le titre du message d'erreur sera retourné:

Je n'ai pas écrit moi-même tout formatErrorMessage mais je le trouve très utile.

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

33
2018-02-13 12:30



C'est ce que j'ai fait et cela fonctionne jusqu'à présent dans une application MVC 5.

Le type de retour du contrôleur est 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"};
}

Et du côté client, voici à quoi ressemble la fonction ajax

$.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;
    }
});

19
2018-05-18 22:23



Si quelqu'un est ici comme en 2016 pour la réponse, utilisez .fail() pour la gestion des erreurs comme .error() est obsolète à partir de jQuery 3.0

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

J'espère que ça aide


15
2017-12-13 17:41



J'ai trouvé que c'était sympa parce que je pouvais analyser le message que j'envoyais du serveur et afficher un message amical à l'utilisateur sans le stacktrace ...

error: function (response) {
      var r = jQuery.parseJSON(response.responseText);
      alert("Message: " + r.Message);
      alert("StackTrace: " + r.StackTrace);
      alert("ExceptionType: " + r.ExceptionType);
}

14
2017-12-01 21:33



Une solution générale / réutilisable

Cette réponse est fournie pour référence future à tous ceux qui rencontrent ce problème. La solution consiste en deux choses:

  1. Exception personnalisée  ModelStateException qui est levée lorsque la validation échoue sur le serveur (l'état du modèle signale des erreurs de validation lorsque nous utilisons des annotations de données et que nous utilisons des paramètres d'action de contrôleur fortement typés)
  2. Filtre d'erreur d'action du contrôleur personnalisé  HandleModelStateExceptionAttribute capture l'exception personnalisée et renvoie l'état d'erreur HTTP avec l'erreur d'état du modèle dans le corps

Cela fournit l'infrastructure optimale pour que les appels jQuery Ajax utilisent leur plein potentiel avec success et error les gestionnaires.

Code du client

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

Code du serveur

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

    // create new user because validation was successful
}

L'ensemble du problème est détaillé dans ce blog où vous pouvez trouver tout le code pour l'exécuter dans votre application.


13
2018-05-05 08:27



Ceci est probablement dû au fait que les noms de champs JSON n'ont pas de guillemets.

Modifier la structure JSON à partir de:

{welcome:"Welcome"}

à:

{"welcome":"Welcome"}

7
2017-08-14 13:01



Je crois que le gestionnaire de réponse Ajax utilise le code d'état HTTP pour vérifier s'il y avait une erreur.

Donc, si vous venez de lancer une exception Java sur votre code côté serveur, mais la réponse HTTP n'a pas un jQuery code de statut 500 (ou dans ce cas, probablement le XMLHttpRequest objet) va simplement supposer que tout allait bien.

Je dis cela parce que j'ai eu un problème similaire dans ASP.NET où je jetais quelque chose comme une ArgumentException ("Je ne sais pas quoi faire ...") mais le gestionnaire d'erreur ne tirait pas.

J'ai ensuite mis le Response.StatusCode à 500 ou 200 si j'ai eu une erreur ou non.


5
2017-12-19 14:11