jQuery nos ofrece fácil acceso a solciitudes AJAX mediante varios métodos: $.get, $.post, $.ajax, $.getJSON y alguno que otro más. En todos ellos se pueden poner en cola varias funciones diferidas. Por ejemplo, .done(), que se ejecuta cuándo la solicitud Ajax ha concluido satisfactoriamente (esto no quiere decir que el contenido de la respuesta sea satisfactorio), .fail(), que se ejecuta en que caso de que haya ocurrido algún error, u .always(), que se ejecuta en ambos casos:

$.ajax({

    url: "test.html"

}).done( function() {

    alert( 'Success!!' );

}).fail( function() {

    alert( 'Error!!' );

}).always( function() {

    alert( 'Always' );

});

En este tutorial vamos a ver que información se recibe en el callback .fail() y como la podemos utilizar para depurar una aplicación Ajax.

.fail( callback )

Cuándo una solicitud Ajax realizada con jQuery falla, se ejecuta la función callback especificada en .fail(). En el callback se reciben tres argumentos:

$.ajax({
    url: "test.html"
}).fail( function( jqXHR, textStatus, errorThrown ) {
    alert( 'Error!!' );
});

Veamos cada uno de ellos:

  • object jqXHR: es un objeto jqXHR que contiene todos los datos de la solicitud Ajax realizada, incluyendo la propiedad jqXHR.status que contiene, entre otros posibles, el código de estado HTTP de la respuesta.
  • string textStatus: texto que describe el tipo de error, que puede ser, además de null, “abort”, “timeout”, “No Transport” o “parseerror”.
  • string errorThrown: si hay un error HTTP, errorThrown contiene el texto de la cabecera HTTP de estado. Por ejemplo, para un error HTTP 404, errorThrown es “Not found”; para error un HTTP 500 es “Internal Server Error”.

A través de estos tres argumentos tenemos acceso a todos los posibles errores de una solicitud Ajax realizada con jQuery, que pueden ser:

  1. HTTP 404 Error – la URL especificada para la solicitud ajax no se encontró
  2. HTTP 500 Error – error interno del servidor
  3. AJAX JSON Parse Errors
  4. jQuery AJAX Timeout Errors
  5. jQuery AJAX Abort Errors
  6. Errores de conectividad
  7. AJAX no transport error
  8. Otros errores desconocidos

Combinando todo, podríamos detectar cada uno de estos errores a través de .fail() del siguiente modo:

$.ajax({
  url: "test.html"
}).fail( function( jqXHR, textStatus, errorThrown ) {

  if (jqXHR.status === 0) {

    alert('Not connect: Verify Network.');

  } else if (jqXHR.status == 404) {

    alert('Requested page not found [404]');

  } else if (jqXHR.status == 500) {

    alert('Internal Server Error [500].');

  } else if (textStatus === 'parsererror') {

    alert('Requested JSON parse failed.');

  } else if (textStatus === 'timeout') {

    alert('Time out error.');

  } else if (textStatus === 'abort') {

    alert('Ajax request aborted.');

  } else {

    alert('Uncaught Error: ' + jqXHR.responseText);

  }

});

En una web o aplicación cualquiera es bastante normal que haya varias interacciones Ajax y en cada una tendríamos que ejecutar un .fail() similar al anterior. Para evitar esta repetición podemos utilizar jQuery.ajaxSetup() y el parámetro error que veremos a continuación.

El método jQuery.ajaxSetup() y el parámetro error

A través del método jQuery.ajaxSetup() podemos establecer los parámetros por defecto que jQuery utilizará para todas las solicitudes ajax. La sintaxis general tiene esta forma:

jQuery.ajaxSetup({
    param : value
});

El parámetro error permite definir una función callback que se ejecuta cuándo la solicitud Ajax falla y que recibe los mismos argumentos que .fail(). De este modo, podemos definir una función que se ejecute para todas las solicitudes Ajax en caso de fallo y que nos diga que ha pasado;

$.ajaxSetup({

  error: function( jqXHR, textStatus, errorThrown ) {

          if (jqXHR.status === 0) {

            alert('Not connect: Verify Network.');

          } else if (jqXHR.status == 404) {

            alert('Requested page not found [404]');

          } else if (jqXHR.status == 500) {

            alert('Internal Server Error [500].');

          } else if (textStatus === 'parsererror') {

            alert('Requested JSON parse failed.');

          } else if (textStatus === 'timeout') {

            alert('Time out error.');

          } else if (textStatus === 'abort') {

            alert('Ajax request aborted.');

          } else {

            alert('Uncaught Error: ' + jqXHR.responseText);

          }

        }
});

Una vez establecido este error callback predeterminado, se ejecutará para todas las solicitudes ajax que realicemos sin tener que definir un .fail() específico para cada una. Por ejemplo, podríamos utilizar tan solo:

$.get("prueba.html");

Como ventaja añadida, la puerta queda abierta para especificar una función .fail() u otro callback para error si lo necesitamos para una solicitud Ajax específica:

$.ajax({
    url: "test.html",
    error: function( jqXHR, textStatus, errorThrown ) {
        // Otro manejador error
    }
}).fail( function( jqXHR, textStatus, errorThrown ) {
    // Un callback .fail()
});

La utilidad de esta implementación es clara: no nos arreglará el error que podamos tener pero nos mostrará que tipo de error se ha producido, primer e imprescindible paso para poder solucionarlo.

Advertencia para solicitudes cross-domain

La diferencia entre el parámetro error de jQuery.ajax() y .fail() es que error es un evento ajax y .fail() es una función diferida. Por tanto, la función callback definida en error no se ejecutará para solicitudes cross-domain pero si lo hará la definida en .fail().

Referencias

  • Jose

    Error interno del servidor al momento de incluir una clase php
    inlude_once(“hijo.php”); en una llamada $.ajax(,,,url: “padre.php”);

  • Jhon Coneo Borja

    Buenas noches, estoy teniendo problemas con un sitio web me esta dando el error de ajax siguiente: datatables error, he estado testeando y me sale que es un eror 404, como puedo solucionarlo

  • John

    Hola, este es un problema con un método de pago integrado en prestashop, pero el si el problema es con lo hecho con ajax.

    Tengo yo un error de timeout en una respuesta ajax, este el trace desde consola en Chrome
    + Object {readyState: 0, responseJSON: undefined, status: 0, statusText: “timeout”}

    Pueden ayudarme como puedo ir afinando mi control de errores? porque lo que intento es mostrar una url en un iframe (lightbox), obtengo un resultado en json pero por momentos funciona el mostrar el url del response, con otras cargas me muestra este timeout. El código es algo parecido a esto:

    Quizás se deba a una lentitud del sitio? Como podría controlar estos Timeout??

    url_r = "index.php?controller=order-detail&id_order="
    			 $.ajax({
    					type: "POST",
    					  url: url,
    					  data: {pay_type:pay_type ,cart_id:cart_id , expirationtime:expirationtime},
    					  async: true,
    					  dataType: 'json',
    					  beforeSend: function (data) {
    					},
    					error: function (err) {
                                                    $("#myLoading").css({ display : 'none'});	
    						$("#myLoadingOverlay").css({ display : 'none'});
    						console.log(err);
    						exito = 1;
    					}
    				}).done(function( data ) {
    					src = data.orderURLPayment;
    					id_order = data.id_order;
    					exito = 0;
    					$("#myLoadingOverlay").css({ display : 'none'});
    					$("#myLoading").css({ display : 'none'});
    					console.log( "Sample of data:", data.orderURLPayment ) ;
    					if(data.orderURLPayment == null)
    					{
    						Cancelar(id_order);
    					}
    					else
    						OpenLightBox(document.getElementById('openLB'), src ,'Payment', 1024 , 800 , true ,url_r + id_order);
    				});
  • Arismel Lyon O’conner

    Hola, gracias por compartir tu conocimiento
    Quería consultarte algo, resulta que yo envio dos datos por post a un archivo php, y los datos efectivamente llegan solo que en el div que me los muestra aparecen por un momento y se desaparecen y no logro entender ¿por que? Agradezco mucho si puedes echarme una manito gracias 🙂

  • Corovino

    Hola muy interesante tu articulo, quisiera saber un poco más que aquiere decir este tipo de error:

    if (jqXHR.status === 0) {
    alert('Not connect: Verify Network.');

    • Perdonad por tardar tanto, se me pasó este comentario.

      Ese error indica un problema con la conexión a la red. Nada más.

    • daniel delgado rivadeneira

      Antes que nada gracias por el aporte. A mi tambien me muestra el error alert('Not connect: Verify Network.'); pero estoy seguro de que no es ningún problema de conexión. ¿Alguna otra idea de lo que está pasando? Los resultados son jqXHR.status = 0 y textStatus = error.

    • Parece que dáis por hecho que problemas con la red es problemas de conexióna Internet desde vuestro ordenador. Y problemas con la la red y la conexión es mucho más. Por ejemplo, puede que sea el servidor el que está caído.

    • daniel delgado rivadeneira

      Lo que sucede es que mi geoserver me devuelve lo siguiente al realizar una petición por medio de una url:

      {"type":"FeatureCollection","totalFeatures":"unknown","features":[{"type":"Feature","id":"predios_urb_st_cl.518","geometry":null,"properties":{"cc":"160350010158002000"}}],"crs":null}

      Y lo que quiero es tomar el valor de ‘cc’ pero me da el error de conexión y yo asumo que no es problema de conexión ya que la respuesta del geoserver es la correcta. No se si tal vez tiene algo que ver alguna configuración de mi geoserver ya que probando lo mismo con uno externo si funciona.

    • Si hay respuesta, ¿como vas a tener un error de conexión o con la red? Sencillamente no puede ser y no ocurre con el código de ejemplo del tutorial, así que habrá algún error en tú código.

      Puede que simplemente tengas el alert('Not connect: Verify Network.'); puesto de forma incorrecta o puede que esté relacionado con este bug. La única forma de estar seguro es que no lances un alert sino que compruebes los valores de jqXHR.status y textStatus en la respuesta.

    • daniel delgado rivadeneira

      Comento que encontre una solución a mi problema y en mi caso se debió a una configuración de mi geoserver que es a donde hago la petición. En mi servidor existe un archivo web.xml donde tuve que habilitar la opción:

      ENABLE_JSONP
      true

      que se encontraba comentado por defecto. Agradezco el interés y las respuestas a mi caso fueron de mucha ayuda

    • Hola, excelente aporte, muchas gracias. Por favor su ayuda, estoy al borde de la desesperacón….me sigue regresando el mentado error :

      jqXHR.status === 0

      Estoy probando el codigo en FireFox, guardando información de un formulario simple y el tema es que SI guarda la información y aun asi sigue enviando este error. Gracias de antemano por la ayuda.