Cómo manejaría los errores al usar jQuery.ajax()?


Cuando se utiliza jQuery's método ajax para enviar datos de formulario, ¿cuál es la mejor manera de manejar los errores? Este es un ejemplo de cómo podría ser una llamada:

$.ajax({
    url: "userCreation.ashx",
    data: { u:userName, p:password, e:email },
    type: "POST",
    beforeSend: function(){disableSubmitButton();},
    complete: function(){enableSubmitButton();},
    error: function(xhr, statusText, errorThrown){
            // Work out what the error was and display the appropriate message
        },
    success: function(data){
            displayUserCreatedMessage();
            refreshUserList();
        }
});

La solicitud puede fallar por varias razones, como el nombre de usuario duplicado, la dirección de correo electrónico duplicada, etc., y el ashx se escribe para lanzar una excepción cuando esto sucede.

Mi problema parece ser que al lanzar una excepción el ashx hace que el statusText y errorThrown sea indefinido.

Puedo acceder al XMLHttpRequest.responseText que contiene el HTML que constituye la página de error estándar de.net.

Estoy encontrando el título de la página en el responseText y usando el título para averiguar qué error fue lanzado. Aunque tengo la sospecha de que esto se desmoronará cuando habilite páginas de manejo de errores personalizados.

¿Debería estar lanzando los errores en el ashx, o debería estar devolviendo un código de estado como parte de los datos devueltos por la llamada a userCreation.ashx, a continuación, utilizando esto para decidir qué acción tomar?
¿Cómo maneja estas situaciones?

Author: Trix, 2008-08-26

3 answers

¿Debería estar lanzando los errores en el ashx, o debería estar devolviendo un código de estado como parte de los datos devuelto por la llamada a Creación de usuarios.ashx, entonces usando esto para decidir qué acción tomar? ¿Cómo manejar estas situaciones?

Personalmente, si es posible, preferiría manejar esto en el lado del servidor y trabajar un mensaje para el usuario allí. Esto funciona muy bien en un escenario donde solo desea mostrar un mensaje al usuario diciéndole lo que sucedió (mensaje de validación, esencialmente).

Sin embargo, si desea realizar una acción basada en lo que sucedió en el servidor, es posible que desee usar un código de estado y escribir algo de javascript para realizar varias acciones basadas en ese código de estado.

 16
Author: Ian Robinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-26 17:13:37

Para depurar, normalmente solo creo un elemento (en el caso siguiente: <div id="error"></div>) en la página y escribo la XMLHttpRequest en ella:

error: function (XMLHttpRequest, textStatus, errorThrown) {
    $("#error").html(XMLHttpRequest.status + "\n<hr />" + XMLHttpRequest.responseText);
}

Luego puede ver los tipos de errores que están ocurriendo y capturarlos correctamente:

if (XMLHttpRequest.status === 404) // display some page not found error
if (XMLHttpRequest.status === 500) // display some server error

En su ashx, puede lanzar una nueva excepción (por ejemplo, "Usuario no válido", etc.) y luego simplemente analizar que fuera de la XMLHttpRequest.responseText? Para mí cuando recibo un error el XMLHttpRequest.responseText no es el estándar Asp.Net página de error, es un objeto JSON que contiene el error como esto:

{
"Message":"Index was out of range. Must be non-negative and less than the size of the collection.\r\n
Parameter name: index",
"StackTrace":" at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)\r\n 
at etc...",
"ExceptionType":"System.ArgumentOutOfRangeException"
}

Editar: Esto podría deberse a que la función a la que estoy llamando está marcada con estos atributos:

<WebMethod()> _
<ScriptMethod()> _
 20
Author: travis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-26 16:41:11

Ahora tengo un problema en cuanto a qué respuesta aceptar.

Una reflexión adicional sobre el problema me lleva a la conclusión de que estaba lanzando excepciones incorrectamente. Los nombres de usuario duplicados, direcciones de correo electrónico, etc. son problemas esperados durante un proceso de registro y, por lo tanto, no son excepciones, sino simplemente errores. En cuyo caso probablemente no debería lanzar excepciones, sino devolver códigos de error.

Lo que me lleva a pensar que el enfoque de irobinson debería ser el que este caso, especialmente porque el formulario es solo una pequeña parte de la interfaz de usuario que se muestra. Ahora he implementado esta solución y estoy devolviendo xml que contiene un estado y un mensaje opcional que se mostrará. Luego puedo usar jQuery para analizarlo y tomar la acción apropiada: -

success: function(data){
    var created = $("result", data).attr("success");
    if (created == "OK"){
        resetNewUserForm();
        listUsers('');
    } else {
        var errorMessage = $("result", data).attr("message");
        $("#newUserErrorMessage").text(errorMessage).show();
    }
    enableNewUserForm();
}

Sin embargo la respuesta de travis es muy detallada y sería perfecta durante la depuración o si quisiera mostrar un mensaje de excepción al usuario. Definitivamente no estoy recibiendo JSON de vuelta, por lo que probablemente se deba a uno de esos atributos que Travis ha enumerado, ya que no los tengo en mi código.

(Voy a aceptar la respuesta de irobinson, pero votaré la respuesta de Travis. Simplemente se siente extraño aceptar una respuesta que no tiene la mayoría de los votos.)

 4
Author: AidenMontgomery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:30:20