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?
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.
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);
}
});
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);
});
Vous devez convertir la responseText
en JSON. Utilisation de JQuery:
jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);
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) );
})
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;
}
});
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
Cette réponse est fournie pour référence future à tous ceux qui se heurtent à ce problème. La solution consiste en deux choses:
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 des paramètres d'action de contrôleur typés forts)HandleModelStateExceptionAttribute
qui intercepte l'exception personnalisée et renvoie le statut d'erreur HTTP avec une erreur d'état du modèle dans le corpsCela fournit l'infrastructure optimale pour les appels jQuery Ajax afin qu'ils exploitent pleinement leur potentiel avec les gestionnaires success
et error
.
$.ajax({
type: "POST",
url: "some/url",
success: function(data, status, xhr) {
// handle success
},
error: function(xhr, status, error) {
// handle error
}
});
[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.
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);
}
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"}
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); }
});
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.
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'
error:function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
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);
}
}
$("#save").click(function(){
$("#save").ajaxError(function(event,xhr,settings,error){
$(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
});
});
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
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.
$("#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({...
...
...
});
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.
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