web-dev-qa-db-fra.com

gestion des erreurs jQuery Ajax, affichage des messages d'exception personnalisés

Puis-je afficher des messages d'exception personnalisés en tant qu'alerte dans mon message d'erreur jQuery AJAX?

Par exemple, si je souhaite lancer une exception côté serveur via Struts by throw new ApplicationException("User name already exists");, je souhaite intercepter ce message ("le 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);
      }
    });
  }
});

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

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

663

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

xhr.responseText

..dans votre javascript.

328
Sprintstar

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

Voir le script:

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

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

Traitement générique des erreurs Ajax

Si j'ai besoin de faire un peu de 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);
                 });
95
Sanjeev Kumar Dangi

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

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

Si vous appelez asp.net, le message d'erreur intitulé:

Je n'ai pas écrit tout 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) ); 
})
36
Sam Jones

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;
    }
});
20
Cengiz Araz

Si quelqu'un est ici comme en 2016 pour la réponse, utilisez .fail() pour le traitement des erreurs car .error() est obsolète à compter 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
Learner

Une solution générale/réutilisable

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

  1. Exception personnaliséeModelStateException 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 des paramètres d'action de contrôleur typés forts)
  2. Filtre d'erreur d'action du contrôleur personnaliséHandleModelStateExceptionAttribute qui intercepte l'exception personnalisée et renvoie le statut d'erreur HTTP avec une erreur d'état du modèle dans le corps

Cela fournit l'infrastructure optimale pour les appels jQuery Ajax afin qu'ils exploitent pleinement leur potentiel avec les gestionnaires success et error.

Code côté client

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

Code côté 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 cet article de blog où vous pouvez trouver tout le code pour l'exécuter dans votre application.

14
Robert Koritnik

J'ai trouvé cela agréable car je pouvais analyser le message que j'envoyais du serveur et afficher un message amical à l'utilisateur sans la pile.

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

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

Changez la structure JSON de:

{welcome:"Welcome"}

à:

{"welcome":"Welcome"}
7
Guy

jQuery.parseJSON est utile en cas de succès et d'erreur.

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

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

Donc, si vous lancez simplement une exception Java sur le code côté serveur mais que la réponse HTTP n'a pas de code d'état 500, jQuery (ou dans ce cas, l'objet XMLHttpRequest ) supposera simplement que tout s'est bien passé.

Je dis cela parce que j'ai eu un problème similaire dans ASP.NET où je lançais quelque chose comme une exception ArgumentException ("Je ne sais pas quoi faire ..."), mais le gestionnaire d'erreur n'a pas été déclenché.

J'ai ensuite défini le Response.StatusCode sur 500 ou 200, que je sois tombé sur une erreur ou non.

5
Vitor Silva

Vous avez un objet JSON de l'exception levée, dans l'objet xhr. Juste utiliser

alert(xhr.responseJSON.Message);

L'objet JSON expose deux autres propriétés: 'ExceptionType' et 'StackTrace'

5
Edika

 error:function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }
en erreur de code demande ajax pour erreur d’erreur connexion entre client et serveur si vous voulez afficher le message d’erreur de votre application envoyée dans la portée de succès 

tel que 

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

}

5
Wara Haii
$("#save").click(function(){
    $("#save").ajaxError(function(event,xhr,settings,error){
        $(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
    });
});
4
ibrahim ozboluk

Lance une nouvelle exception sur le serveur en utilisant:

Response.StatusCode = 500

Response.StatusDescription = ex.Message ()

Je crois que la StatusDescription est renvoyée à l'appel Ajax ...

Exemple:

        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
3
Steffan

Bien que de nombreuses années se soient écoulées depuis que cette question a été posée, je ne trouve toujours pas xhr.responseText comme réponse que je cherchais. Il m'a renvoyé une chaîne au format suivant:

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

que je ne veux certainement pas montrer aux utilisateurs. Ce que je cherchais est quelque chose comme ci-dessous:

alert(xhr.responseJSON.message);

xhr.responseJSON.message me donne le message exact de l’objet Json qui peut être montré aux utilisateurs.

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

S'il y a un formulaire est soumettre avec valider

utilisez simplement le reste du code

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

... ... });

1
Monzur

Cette fonction génère essentiellement des clés d'API aléatoires uniques. Dans le cas contraire, une boîte de dialogue contextuelle avec un message d'erreur apparaît

In View Page:

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

De contrôleur:

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

Le paramètre facultatif callback spécifie une fonction de rappel à exécuter lorsque la méthode load () est terminée. La fonction de rappel peut avoir différents paramètres:

Type: Fonction (jqXHR jqXHR, String textStatus, String errorThrown)

Une fonction à appeler si la requête échoue. La fonction reçoit trois arguments: l'objet jqXHR (dans jQuery 1.4.x, XMLHttpRequest), une chaîne décrivant le type d'erreur survenu et un objet exception facultatif, le cas échéant. Les valeurs possibles pour le deuxième argument (outre null) sont "timeout", "erreur", "abort" et "parsererror". Lorsqu'une erreur HTTP se produit, errorThrown reçoit la partie textuelle de l'état HTTP, telle que "Introuvable" ou "Erreur de serveur interne". À partir de jQuery 1.5, le paramètre d'erreur peut accepter un tableau de fonctions. Chaque fonction sera appelée à tour de rôle. Remarque: Ce gestionnaire n'est pas appelé pour les requêtes de script interdomaine et JSONP interdomaine. 

0
Nishanth ॐ

Nous devons d’abord définir <serviceDebug includeExceptionDetailInFaults = "True" /> dans web.config:

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

En plus de cela au niveau jquery dans la partie erreur, vous devez analyser une réponse d'erreur contenant une exception telle que:

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

Ensuite, en utilisant r.Message, vous pouvez afficher un texte d’exception.

Vérifiez le code complet: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

0
Avinash