773 votes

Traitement des erreurs par jQuery Ajax, affichage de messages d'exception personnalisés

Existe-t-il un moyen d'afficher des messages d'exception personnalisés sous forme d'alerte dans mon message d'erreur Ajax jQuery ?

Par exemple, si je veux lancer une exception du côté du serveur par le biais de Struts par "throw new ApplicationException("User name already exists") ;", je veux attraper ce message (nom d'utilisateur déjà existant) dans le message d'erreur de 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'ai déclenché une erreur, j'obtiens undefined et le code d'état est 500.

Je ne sais pas où je me trompe. Que puis-je faire pour résoudre ce problème ?

375voto

Sprintstar Points 3665

Assurez-vous de régler Response.StatusCode à quelque chose d'autre que 200. Rédigez le message de votre exception en utilisant Response.Write alors utilisez...

xhr.responseText

dans votre javascript.

9 votes

C'est toujours la bonne façon de faire après 2 ans et demi... :) Je suis allé un peu plus loin et j'ai retourné mon propre objet JSON d'erreur qui peut gérer des erreurs simples ou multiples, ce qui est très bien pour la validation de formulaires côté serveur.

0 votes

@Wilson C'était comme indiqué dans les autres réponses bien notées ici.

3 votes

Je suis maintenant en 2014. Une ère dominée par JSON. Donc j'utilise xhr.responseJSON . :D

232voto

AlexMAS Points 1084

Contrôleur :

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

Voir script :

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

15 votes

Ce n'est pas une réponse "correcte" à la question mais cela montre très certainement une solution de haut niveau au problème... Bien joué !

3 votes

Je fais quelque chose de similaire. Cela fonctionne bien si tout est fait sur le boîtier de développement. Si j'essaie de me connecter à partir d'une autre boîte sur le réseau, le xhr.responseText contient le html de la page d'erreur générique et non pas mon message personnalisé, cf. stackoverflow.com/questions/3882752/

6 votes

Je pense que vous devriez également ajouter response.StatusCode = 500 ; à la méthode OnException.

99voto

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

           }
 }

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

Traitement générique des erreurs Ajax

Si j'ai besoin de faire un traitement générique des erreurs pour toutes les requêtes ajax. Je vais définir le gestionnaire ajaxError et afficher l'erreur dans 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' : "Unauthorised access.",
                '403' : "Forbidden resouce can't be accessed",
                '500' : "Internal Server Error.",
                '503' : "Service Unavailable"
            };
            if (x.status) {
                message =statusErrorMap[x.status];
                                if(!message){
                                      message="Unknow 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="Unknow Error \n.";
            }
            $(this).css("display","inline");
            $(this).html(message);
                 });

85voto

Sydney Points 3368

Vous devez convertir le responseText en JSON. Utilisation de JQuery :

jsonValue = jQuery.parseJSON( jqXHR.responseText );

5 votes

+1 car c'est actuellement la seule réponse CORRECTE à cette question ! Vous pouvez appeler "jsonValue.Message" pour obtenir le message d'exception.

2 votes

En fait, ce n'est pas la bonne réponse car la question ne porte pas sur JSON et l'exemple de requête demande spécifiquement le HTML comme réponse.

0 votes

+1 Correct. Remarque : il est courant d'envoyer un objet codé en JSON par le biais de jqXHR.responseText (chaîne). Vous pouvez ensuite utiliser l'objet jsonValue comme vous le souhaitez. Utilisez la console Firebug pour examiner la réponse en utilisant console.log(jsonValue).

39voto

Sam Jones Points 765

S'il s'agit d'un appel à asp.net, cela renverra le titre du message d'erreur :

Je n'ai pas écrit tout le formatErrorMessage moi-même 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) ); 
})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X