success - jquery put




Tratamento de erros do jQuery Ajax, mostrar mensagens de exceção personalizadas (14)

Existe alguma maneira eu posso mostrar mensagens de exceção personalizada como um alerta na minha mensagem de erro jQuery AJAX?

Por exemplo, se eu quiser lançar uma exceção no lado do servidor via Struts , throw new ApplicationException("User name already exists"); , Eu quero pegar essa mensagem ('nome de usuário já existe') na mensagem de erro 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);
      }
    });
  }
});

No segundo alerta, onde eu alerta o erro lançado, estou ficando undefined e o código de status é 500.

Não tenho certeza de onde estou indo errado. O que posso fazer para corrigir esse problema?


Uma solução geral / reutilizável

Essa resposta é fornecida para referência futura a todos os que se deparam com esse problema. Solução consiste em duas coisas:

  1. Exceção personalizada ModelStateException que é acionada quando a validação falha no servidor (o estado do modelo relata erros de validação quando usamos anotações de dados e usamos parâmetros de ação de controlador de tipo forte)
  2. Filtro de erro de ação do controlador personalizado HandleModelStateExceptionAttribute que captura a exceção personalizada e retorna o status do erro HTTP com erro de estado do modelo no corpo

Isso fornece a infraestrutura ideal para que as chamadas do jQuery Ajax usem todo o seu potencial com manipuladores de success e error .

Código do lado do cliente

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

Código do lado do servidor

[HandleModelStateException]
public ActionResult Create(User user)
{
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }

    // create new user because validation was successful
}

Todo o problema é detalhado neste post do blog, onde você pode encontrar todo o código para executar isso em seu aplicativo.


Embora já se passaram muitos anos desde que essa pergunta foi feita, ainda não encontro o xhr.responseText como a resposta que eu estava procurando. Ele me retornou string no seguinte formato:

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

que eu definitivamente não quero mostrar aos usuários. O que eu estava procurando é algo como abaixo:

alert(xhr.responseJSON.message);

xhr.responseJSON.message me fornece a mensagem exata do objeto Json, que pode ser mostrada para os usuários.


Eu acredito que o manipulador de resposta do Ajax usa o código de status HTTP para verificar se houve um erro.

Portanto, se você simplesmente lançar uma exceção Java no código do lado do servidor, mas a resposta HTTP não tiver um código de status 500, jQuery (ou, nesse caso, provavelmente, o objeto XMLHttpRequest ) assumirá que tudo está bem.

Eu estou dizendo isso porque eu tive um problema semelhante no asp.net, onde eu estava jogando algo como um ArgumentException ("não sei o que fazer ..."), mas o manipulador de erro não estava disparando.

Em seguida, defino o Response.StatusCode para 500 ou 200, independentemente de ter um erro ou não.


Isso é o que eu fiz e funciona até agora em um aplicativo MVC 5.

O tipo de retorno do controlador é 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"};
}

E no lado do cliente é assim que a função ajax se parece

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

Lançar uma nova exceção no servidor usando:

Response.StatusCode = 500

Response.StatusDescription = ex.Message ()

Eu acredito que o StatusDescription é retornado para a chamada do Ajax ...

Exemplo:

        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

Primeiro, precisamos definir <serviceDebug includeExceptionDetailInFaults = "True" /> no web.config:

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

Além disso, no nível do jquery na parte do erro, é necessário analisar a resposta de erro que contém exceção, como:

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

Então, usando o r.Message, você pode mostrar atentamente o texto da exceção.

Verifique o código completo: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html


Se fizer uma chamada para o asp.net, isso retornará o título da mensagem de erro:

Eu não escrevi todo o formatErrorMessage sozinho, mas acho muito ú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) ); 
})

Verifique se você está definindo Response.StatusCode para algo diferente de 200. Escreva a mensagem da sua exceção usando Response.Write e use ...

xhr.responseText

.. no seu javascript.


Você tem um objeto JSON da exceção lançada no objeto xhr. Apenas use

alert(xhr.responseJSON.Message);

O objeto JSON expõe duas outras propriedades: 'ExceptionType' e 'StackTrace'


jQuery.parseJSON é útil para sucesso e erro.

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

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

Visualizar script:

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

ServerSide:

     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

           }
 }

ClientSide:

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

Manipulação Genérica de Erros Ajax

Se eu precisar fazer algum tratamento genérico de erros para todas as solicitações do ajax. Vou definir o manipulador ajaxError e exibir o erro em um div chamado errorcontainer na parte superior do conteúdo 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);
                 });

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

Se houver algum formulário, envie com validação

basta usar o resto do 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);
    });
});




custom-exceptions