mostrar - jquery ajax success error
jQuery Ajax manejo de errores, muestra mensajes de excepción personalizados (20)
¿Hay alguna manera de mostrar mensajes de excepción personalizados como una alerta en mi mensaje de error jQuery AJAX?
Por ejemplo, si quiero lanzar una excepción en el lado del servidor a través de Struts throw new ApplicationException("User name already exists");
Quiero capturar este mensaje (''el nombre de usuario ya existe'') en el mensaje de error 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);
}
});
}
});
En la segunda alerta, donde alerta el error arrojado, me estoy volviendo undefined
y el código de estado es 500.
No estoy seguro de dónde voy mal. ¿Qué puedo hacer para solucionar este problema?
Una solución general / reutilizable.
Esta respuesta se proporciona para futuras referencias a todos aquellos que se topan con este problema. La solución consiste en dos cosas:
- Excepción personalizada La excepción
ModelStateException
que se lanza cuando la validación falla en el servidor (el estado del modelo informa errores de validación cuando usamos anotaciones de datos y usamos parámetros de acción de controlador tipificados) - Controlador de acciones del controlador personalizado filtro
HandleModelStateExceptionAttribute
queHandleModelStateExceptionAttribute
una excepción personalizada y devuelve el estado de error HTTP con un error de estado del modelo en el cuerpo
Esto proporciona la infraestructura óptima para que las llamadas jQuery Ajax utilicen todo su potencial con controladores de success
y error
.
Código del lado del cliente
$.ajax({
type: "POST",
url: "some/url",
success: function(data, status, xhr) {
// handle success
},
error: function(xhr, status, error) {
// handle error
}
});
Código del lado del servidor
[HandleModelStateException]
public ActionResult Create(User user)
{
if (!this.ModelState.IsValid)
{
throw new ModelStateException(this.ModelState);
}
// create new user because validation was successful
}
El problema completo se detalla en esta publicación del blog donde puede encontrar todo el código para ejecutar esto en su aplicación.
Asegúrese de que está configurando Response.StatusCode
en algo diferente a 200. Escriba el mensaje de su excepción usando Response.Write
, luego use ...
xhr.responseText
..en su javascript.
Aunque han pasado muchos años desde que se hizo esta pregunta, todavía no encuentro xhr.responseText
como la respuesta que estaba buscando. Me devolvió la cadena en el siguiente formato:
"{"error":true,"message":"The user name or password is incorrect"}"
que definitivamente no quiero mostrar a los usuarios. Lo que estaba buscando es algo como abajo:
alert(xhr.responseJSON.message);
xhr.responseJSON.message
me da el mensaje exacto del objeto Json que se puede mostrar a los usuarios.
Creo que el controlador de respuesta Ajax usa el código de estado HTTP para verificar si hubo un error.
Entonces, si acaba de lanzar una excepción de Java en el código del lado del servidor, pero la respuesta HTTP no tiene un código de estado 500 jQuery (o en este caso, probablemente el objeto XMLHttpRequest ) asumirá que todo estaba bien.
Lo digo porque tuve un problema similar en ASP.NET donde estaba lanzando algo como una ArgumentException ("No sé qué hacer ...") pero el controlador de errores no estaba disparando.
Luego puse el Response.StatusCode
en 500 o 200 ya sea que haya tenido un error o no.
Descubrí que esto era agradable porque podía analizar el mensaje que estaba enviando desde el servidor y mostrar un mensaje amigable al usuario sin el seguimiento de pila ...
error: function (response) {
var r = jQuery.parseJSON(response.responseText);
alert("Message: " + r.Message);
alert("StackTrace: " + r.StackTrace);
alert("ExceptionType: " + r.ExceptionType);
}
Esto es lo que hice y hasta ahora funciona en una aplicación MVC 5.
El tipo de devolución del controlador es 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"};
}
Y en el lado del cliente, así es como se ve la función 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;
}
});
Lanzar una nueva excepción en el servidor usando:
Response.StatusCode = 500
Response.StatusDescription = ex.Message ()
Creo que la Descripción de estado se devuelve a la llamada Ajax ...
Ejemplo:
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
Necesitas convertir el responseText
a JSON. Usando JQuery:
jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);
Primero necesitamos configurar <serviceDebug includeExceptionDetailInFaults = "True" /> en web.config:
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
**<serviceDebug includeExceptionDetailInFaults="true" />**
</behavior>
</serviceBehaviors>
Además de eso, a nivel de jquery en la parte de error, debe analizar la respuesta de error que contiene una excepción como:
.error(function (response, q, t) {
var r = jQuery.parseJSON(response.responseText);
});
Luego, utilizando r.Message puede mostrar de forma activa el texto de excepción.
Verifique el código completo: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html
Probablemente esto se deba a que los nombres de campo JSON no tienen comillas.
Cambia la estructura JSON desde:
{welcome:"Welcome"}
a:
{"welcome":"Welcome"}
Si alguien está aquí como en 2016 para la respuesta, use .fail()
para el manejo de errores, ya que .error()
está en desuso a partir de jQuery 3.0
$.ajax( "example.php" )
.done(function() {
alert( "success" );
})
.fail(function(jqXHR, textStatus, errorThrown) {
//handle error here
})
Espero que ayude
Si realiza una llamada a asp.net, esto devolverá el título del mensaje de error:
No escribí todo el formatErrorMessage pero lo encuentro muy útil.
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) );
})
Tiene un objeto JSON de la excepción lanzada, en el objeto xhr. Solo usa
alert(xhr.responseJSON.Message);
El objeto JSON expone otras dos propiedades: ''ExceptionType'' y ''StackTrace''
jQuery.parseJSON es útil para el éxito y el error.
$.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); }
});
Básicamente, esta función genera claves de API aleatorias únicas y, en caso de no hacerlo, aparece un cuadro de diálogo emergente con un mensaje de error.
En la página de visualización:
<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>
Desde el controlador:
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));
}
El parámetro opcional de devolución de llamada especifica una función de devolución de llamada para ejecutarse cuando se completa el método load (). La función de devolución de llamada puede tener diferentes parámetros:
Tipo: Función (jqXHR jqXHR, String textStatus, String errorThrown)
Una función a llamar si la solicitud falla. La función recibe tres argumentos: el objeto jqXHR (en jQuery 1.4.x, XMLHttpRequest), una cadena que describe el tipo de error que ocurrió y un objeto de excepción opcional, si se produjo uno. Los valores posibles para el segundo argumento (además de nulo) son "timeout", "error", "abort" y "parsererror". Cuando se produce un error de HTTP, errorThrown recibe la parte textual del estado de HTTP, como "No encontrado" o "Error interno del servidor". A partir de jQuery 1.5, la configuración de error puede aceptar una serie de funciones. Cada función será llamada a su vez. Nota: este controlador no se llama para secuencias de comandos de dominio cruzado y JSONP de dominio cruzado.
Controlador:
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");
}
}
Ver script:
$.ajax({
type: "post", url: "/SomeController/SomeAction",
success: function (data, text) {
//...
},
error: function (request, status, error) {
alert(request.responseText);
}
});
Lado del servidor:
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
}
}
Lado del cliente:
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");
}
}
});
Manejo de errores de Ajax genérico
Si necesito hacer algún manejo de error genérico para todas las solicitudes ajax. Estableceré el controlador ajaxError y mostraré el error en un div llamado errorcontainer en la parte superior del contenido 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);
});
error:function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
como
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);
}
}
$("#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
});
});
Si hay alguna forma se enviará con validar.
simplemente usa el resto del código
$("#fmlogin").validate({...
... ... });
$("#save").click(function(){
$("#save").ajaxError(function(event,xhr,settings,error){
$(this).html{''error: '' (xhr ?xhr.status : '''')+ '' '' + (error ? error:''unknown'') + ''page: ''+settings.url);
});
});