简体   繁体   English

jQuery Ajax 错误处理,显示自定义异常消息

[英]jQuery Ajax error handling, show custom exception messages

Is there some way I can show custom exception messages as an alert in my jQuery AJAX error message?有什么方法可以在我的 jQuery AJAX 错误消息中将自定义异常消息显示为警报?

For example, if I want to throw an exception on the server side via Struts by throw new ApplicationException("User name already exists");例如,如果我想通过Struts在服务器端通过throw new ApplicationException("User name already exists");抛出异常throw new ApplicationException("User name already exists"); , I want to catch this message ('user name already exists') in the jQuery AJAX error message. ,我想在 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);
      }
    });
  }
});

On the second alert, where I alert the thrown error, I am getting undefined and the status code is 500.在我警告抛出的错误的第二个警报中,我变得undefined并且状态代码为 500。

I am not sure where I am going wrong.我不确定我哪里出错了。 What can I do to fix this problem?我能做些什么来解决这个问题?

Make sure you're setting Response.StatusCode to something other than 200. Write your exception's message using Response.Write , then use...确保将Response.StatusCode设置为 200 以外的值。使用Response.Write编写异常消息,然后使用...

xhr.responseText

..in your javascript. ..在你的javascript中。

Controller:控制器:

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

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

Generic Ajax Error Handling通用 Ajax 错误处理

If I need to do some generic error handling for all the ajax requests.如果我需要为所有 ajax 请求做一些通用的错误处理。 I will set the ajaxError handler and display the error on a div named errorcontainer on the top of html content.我将设置 ajaxError 处理程序并在 html 内容顶部名为 errorcontainer 的 div 上显示错误。

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

You need to convert the responseText to JSON.您需要将responseText转换为 JSON。 Using JQuery:使用 JQuery:

jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);

If making a call to asp.net, this will return the error message title:如果调用 asp.net,这将返回错误消息标题:

I didn't write all of formatErrorMessage myself but i find it very useful.我没有自己写所有的 formatErrorMessage 但我发现它非常有用。

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

This is what I did and it works so far in a MVC 5 application.这就是我所做的,到目前为止它在 MVC 5 应用程序中有效。

Controller's return type is ContentResult.控制器的返回类型是 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"};
}

And on client side this is what ajax function looks like在客户端,这就是 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;
    }
});

If someone is here as in 2016 for the answer, use .fail() for error handling as .error() is deprecated as of jQuery 3.0如果有人像 2016 年一样在这里寻找答案,请使用.fail()进行错误处理,因为.error()从 jQuery 3.0 开始已弃用

$.ajax( "example.php" )
  .done(function() {
    alert( "success" );
  })
  .fail(function(jqXHR, textStatus, errorThrown) {
    //handle error here
  })

I hope it helps我希望它有帮助

A general/reusable solution通用/可重用的解决方案

This answer is provided for future reference to all those that bump into this problem.提供此答案以供将来所有遇到此问题的人参考。 Solution consists of two things:解决方案包括两件事:

  1. Custom exception ModelStateException that gets thrown when validation fails on the server (model state reports validation errors when we use data annotations and use strong typed controller action parameters)在服务器上验证失败时抛出的自定义异常ModelStateException (当我们使用数据注释和使用强类型控制器操作参数时,模型状态报告验证错误)
  2. Custom controller action error filter HandleModelStateExceptionAttribute that catches custom exception and returns HTTP error status with model state error in the body自定义控制器操作错误过滤器HandleModelStateExceptionAttribute捕获自定义异常并返回 HTTP 错误状态,主体中包含模型状态错误

This provides the optimal infrastructure for jQuery Ajax calls to use their full potential with success and error handlers.这为 jQuery Ajax 调用提供了最佳基础设施,以充分利用successerror处理程序的潜力。

Client side code客户端代码

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

Server side code服务端代码

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

    // create new user because validation was successful
}

The whole problem is detailed in this blog post where you can find all the code to run this in your application. 这篇博文详细介绍了整个问题,您可以在其中找到在您的应用程序中运行它的所有代码。

 error:function (xhr, ajaxOptions, thrownError) { alert(xhr.status); alert(thrownError); }
in code error ajax request for catch error connect between client to server if you want show error message of your application send in success scope 在代码错误 ajax 请求中,如果您想在成功范围内显示您的应用程序发送的错误消息,则在客户端到服务器之间连接捕获错误的请求

such as比如

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

I found this to be nice because I could parse out the message I was sending from the server and display a friendly message to the user without the stacktrace...我发现这很好,因为我可以解析我从服务器发送的消息,并在没有堆栈跟踪的情况下向用户显示一条友好的消息......

error: function (response) {
      var r = jQuery.parseJSON(response.responseText);
      alert("Message: " + r.Message);
      alert("StackTrace: " + r.StackTrace);
      alert("ExceptionType: " + r.ExceptionType);
}

This is probably caused by the JSON field names not having quotation marks.这可能是由于 JSON 字段名称没有引号引起的。

Change the JSON structure from:将 JSON 结构从:

{welcome:"Welcome"}

to:到:

{"welcome":"Welcome"}

This function basically generates unique random API key's and in case if it doesn't then pop-up dialog box with error message appears此函数基本上生成唯一的随机 API 密钥,如果没有,则会出现带有错误消息的弹出对话框

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>

From Controller:来自控制器:

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

The optional callback parameter specifies a callback function to run when the load() method is completed.可选的回调参数指定在 load() 方法完成时要运行的回调函数。 The callback function can have different parameters:回调函数可以有不同的参数:

Type: Function( jqXHR jqXHR, String textStatus, String errorThrown )类型:函数( jqXHR jqXHR, String textStatus, String errorThrown )

A function to be called if the request fails.请求失败时调用的函数。 The function receives three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a string describing the type of error that occurred and an optional exception object, if one occurred.该函数接收三个参数:jqXHR(在 jQuery 1.4.x 中,XMLHttpRequest)对象、描述发生的错误类型的字符串和可选的异常对象(如果发生)。 Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror".第二个参数(除了 null)的可能值是“超时”、“错误”、“中止”和“解析器错误”。 When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."当发生 HTTP 错误时,errorThrown 会接收 HTTP 状态的文本部分,例如“未找到”或“内部服务器错误”。 As of jQuery 1.5, the error setting can accept an array of functions.从 jQuery 1.5 开始,错误设置可以接受函数数组。 Each function will be called in turn.每个函数都会被依次调用。 Note: This handler is not called for cross-domain script and cross-domain JSONP requests.注意:对于跨域脚本和跨域 JSONP 请求,不会调用此处理程序。

You have a JSON object of the exception thrown, in the xhr object.您在 xhr 对象中有一个抛出异常的 JSON 对象。 Just use只需使用

alert(xhr.responseJSON.Message);

The JSON object expose two other properties: 'ExceptionType' and 'StackTrace' JSON 对象公开了另外两个属性:“ExceptionType”和“StackTrace”

I believe the Ajax response handler uses the HTTP status code to check if there was an error.我相信 Ajax 响应处理程序使用 HTTP 状态代码来检查是否有错误。

So if you just throw a Java exception on your server side code but then the HTTP response doesn't have a 500 status code jQuery (or in this case probably the XMLHttpRequest object) will just assume that everything was fine.因此,如果您只是在服务器端代码上抛出 Java 异常,但 HTTP 响应没有 500 状态代码 jQuery(或者在这种情况下可能是XMLHttpRequest对象)将假设一切正常。

I'm saying this because I had a similar problem in ASP.NET where I was throwing something like a ArgumentException("Don't know what to do...") but the error handler wasn't firing.我这么说是因为我在 ASP.NET 中遇到了类似的问题,我抛出了类似 ArgumentException("Don't know what to do...") 但错误处理程序没有触发的问题。

I then set the Response.StatusCode to either 500 or 200 whether I had an error or not.然后,无论是否有错误,我都将Response.StatusCode设置为 500 或 200。

jQuery.parseJSON is useful for success and error. jQuery.parseJSON 对于成功和错误都很有用。

$.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); }
});
$("#save").click(function(){
    $("#save").ajaxError(function(event,xhr,settings,error){
        $(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
    });
});

Throw a new exception on server using:使用以下命令在服务器上抛出一个新异常:

Response.StatusCode = 500 Response.StatusCode = 500

Response.StatusDescription = ex.Message() Response.StatusDescription = ex.Message()

I believe that the StatusDescription is returned to the Ajax call...我相信 StatusDescription 返回给 Ajax 调用......

Example:示例:

        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

Although it has been many years since this question is asked, I still don't find xhr.responseText as the answer I was looking for.尽管问这个问题已经很多年了,但我仍然没有找到xhr.responseText作为我正在寻找的答案。 It returned me string in the following format:它以以下格式返回我的字符串:

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

which I definitely don't want to show to the users.我绝对不想向用户展示。 What I was looking for is something like below:我正在寻找的是如下所示的内容:

alert(xhr.responseJSON.message);

xhr.responseJSON.message gives me the exact message from the Json Object which can be shown to the users. xhr.responseJSON.message为我提供了来自 Json 对象的确切消息,可以向用户显示。

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

If there is any form is submit with validate如果有任何表单提交验证

simply use the rest of the code只需使用其余的代码

$("#fmlogin").validate({...

... ... });

First we need to set <serviceDebug includeExceptionDetailInFaults="True" /> in web.config:首先我们需要在 web.config 中设置 <serviceDebug includeExceptionDetailInFaults="True" /> :

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

In addition to that at jquery level in error part you need to parse error response that contains exception like:除了在错误部分的 jquery 级别之外,您还需要解析包含以下异常的错误响应:

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

Then using r.Message you can actully show exception text.然后使用 r.Message 您可以实际显示异常文本。

Check complete code: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html检查完整代码: http : //www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

In my case, I just removed HTTP VERB from controller.就我而言,我刚刚从控制器中删除了 HTTP VERB。

    **//[HttpPost]**   ---- just removed this verb
    public JsonResult CascadeDpGetProduct(long categoryId)
    {
       
        List<ProductModel> list = new List<ProductModel>();
        list = dp.DpProductBasedOnCategoryandQty(categoryId);
        return Json(new SelectList(list, "Value", "Text", JsonRequestBehavior.AllowGet));
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM