Xử lý lỗi jQuery Ajax, hiển thị các thông báo ngoại lệ tùy chỉnh


728

Có cách nào để tôi có thể hiển thị các thông báo ngoại lệ tùy chỉnh dưới dạng cảnh báo trong thông báo lỗi AJAX của jQuery không?

Ví dụ, nếu tôi muốn ném một ngoại lệ ở phía máy chủ thông qua Struts bởi throw new ApplicationException("User name already exists");, tôi muốn bắt thông điệp này ( 'tên người dùng đã tồn tại') trong thông báo lỗi 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);
      }
    });
  }
});

Trong cảnh báo thứ hai, nơi tôi thông báo lỗi đã ném, tôi đang nhận được undefinedvà mã trạng thái là 500.

Tôi không chắc chắn tôi sẽ đi sai ở đâu. Tôi có thể làm gì để khắc phục vấn đề này?

Câu trả lời:


357

Đảm bảo bạn đang cài đặt Response.StatusCodemột cái gì đó ngoài 200. Viết tin nhắn ngoại lệ của bạn bằng cách sử dụng Response.Write, sau đó sử dụng ...

xhr.responseText

.. trong javascript của bạn.


9
Đây vẫn là cách thực hiện chính xác sau 2 năm rưỡi ... :) Tôi đã đi xa hơn một chút và thực sự trả về đối tượng JSON lỗi của riêng tôi có thể xử lý một hoặc nhiều lỗi, khá tốt cho xác thực dạng phía máy chủ.
AlexCode

@Wilson Nó được thể hiện trong các câu trả lời được đánh giá cao khác ở đây.
Sprintstar

3
Bây giờ là năm 2014. Thời đại thống trị JSON. Vì vậy, tôi sử dụng xhr.responseJSON. : D
Ravi

5
xhr.responseJSON chỉ được đặt nếu bạn đảm bảo rằng loại meta được đặt (ví dụ: "Loại nội dung: ứng dụng / json"). Đó là một vấn đề tôi vừa gặp phải; answerText đã được đặt - answerJSON thì không.
Igor

217

Điều khiển:

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

Xem kịch bản:

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

13
Đây không phải là một câu trả lời "chính xác" cho câu hỏi nhưng nó chắc chắn cho thấy một giải pháp cấp cao hơn cho vấn đề ... Thật tuyệt!
Ryan Anderson

3
Tôi đang làm một cái gì đó tương tự. Nó hoạt động tốt nếu mọi thứ được thực hiện trên hộp phát triển. Nếu tôi cố gắng kết nối từ một hộp khác nhau trên mạng, xhr.responseText chứa html trang lỗi chung chung và không thông báo tùy chỉnh của tôi, xem stackoverflow.com/questions/3882752/...
jamiebarrow

6
Tôi tin rằng bạn cũng nên thêm phản hồi.StatusCode = 500; dòng đến phương thức OnException.
Alexander Prokofyev

4
Tôi đã điều chỉnh điều này - vì tôi muốn có 500 mã trạng thái, nhưng để có thông báo ngoại lệ trong mô tả trạng thái (thay vì "Lỗi máy chủ nội bộ") - response.StatusCode = (int)HttpStatusCode.InternalServerError;response.StatusDescription = filterContext.Exception.Message;
Kram

4
Nếu bạn đang sử dụng IIS7 trở lên, bạn có thể cần thêm: answer.TrySkipIisCustomErrors = true;
James Gaunt

97

Máy chủ

     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

           }
 }

Phía khách hàng:

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

Xử lý lỗi Ajax chung

Nếu tôi cần thực hiện một số xử lý lỗi chung cho tất cả các yêu cầu ajax. Tôi sẽ thiết lập trình xử lý ajaxError và hiển thị lỗi trên div có tên lỗi trên đầu nội dung 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);
                 });

81

Bạn cần chuyển đổi responseTextsang JSON. Sử dụng JQuery:

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

5
+1 'vì hiện tại đây là câu trả lời ĐÚNG duy nhất cho câu hỏi này! Bạn có thể gọi "jsonValue.Message" để nhận thông báo ngoại lệ.
Thuyền trưởng Sensible

2
Trên thực tế, đây không phải là câu trả lời chính xác vì câu hỏi không hỏi về JSON và yêu cầu ví dụ cụ thể yêu cầu HTML làm câu trả lời.
SingleShot

+1 đúng. Lưu ý, Việc gửi một đối tượng được mã hóa JSON thông qua jqXHR.responseText (chuỗi) là điều phổ biến. Sau đó, bạn có thể sử dụng Đối tượng jsonValue như thế nào bạn cần. Sử dụng bảng điều khiển Fireorms để xem lại phản hồi bằng console.log (jsonValue).
jjwdesign

Điều này mang lại cho tôi Sy Uncaught SyntaxError: Số bất ngờ '
Ben Racicot

1
Đối tượng JSON được phân tích cú pháp được cung cấp thông qua thuộc tính answerJSON của đối tượng jqXHR. Vì vậy, không cần phân tích thuộc tính answerText. Bạn chỉ có thể làm: console.log (jqXHR.responseJSON.Message)
Eric D'Souza

37

Nếu thực hiện cuộc gọi đến asp.net, điều này sẽ trả về tiêu đề thông báo lỗi:

Tôi đã không tự viết tất cả các định dạngErrorMessage nhưng tôi thấy nó rất hữu ích.

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

22

Đây là những gì tôi đã làm và nó hoạt động cho đến nay trong một ứng dụng MVC 5.

Kiểu trả về của bộ điều khiển là 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"};
}

Và về phía khách hàng, đây là chức năng của 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;
    }
});

20

Nếu ai đó ở đây như năm 2016 cho câu trả lời, hãy sử dụng .fail()để xử lý lỗi vì .error()không được chấp nhận kể từ jQuery 3.0

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

Tôi hy vọng nó sẽ giúp


2
jqXHR.error()bị phản đối (thực sự bị loại bỏ) trong jQuery 3.0, nhưng các cuộc gọi lại errorvà không được phản đối, theo như tôi biết. success$.ajax()
Neil Conway

16

Một giải pháp chung / tái sử dụng

Câu trả lời này được cung cấp để tham khảo trong tương lai cho tất cả những người gặp phải vấn đề này. Giải pháp bao gồm hai điều:

  1. Ngoại lệ tùy chỉnh ModelStateException bị ném khi xác thực thất bại trên máy chủ (trạng thái mô hình báo cáo lỗi xác thực khi chúng tôi sử dụng chú thích dữ liệu và sử dụng tham số hành động của bộ điều khiển được gõ mạnh)
  2. Bộ lọc lỗi hành động của bộ điều khiển HandleModelStateExceptionAttribute tùy chỉnh bắt ngoại lệ tùy chỉnh và trả về trạng thái lỗi HTTP với lỗi trạng thái mô hình trong phần thân

Điều này cung cấp cơ sở hạ tầng tối ưu cho các lệnh gọi jQuery Ajax để sử dụng toàn bộ tiềm năng của chúng với successerror xử lý.

Mã phía khách hàng

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

Mã phía máy chủ

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

    // create new user because validation was successful
}

Toàn bộ vấn đề được nêu chi tiết trong bài đăng trên blog này , nơi bạn có thể tìm thấy tất cả các mã để chạy mã này trong ứng dụng của mình.


14

Tôi thấy điều này thật tuyệt vì tôi có thể phân tích tin nhắn tôi đang gửi từ máy chủ và hiển thị một tin nhắn thân thiện cho người dùng mà không cần stacktrace ...

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

11

 error:function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }
trong lỗi mã ajax yêu cầu bắt lỗi kết nối giữa máy khách với máy chủ nếu bạn muốn hiển thị thông báo lỗi của ứng dụng của bạn gửi trong phạm vi thành công

nhu la

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

}


7

Điều này có thể do tên trường JSON không có dấu ngoặc kép.

Thay đổi cấu trúc JSON từ:

{welcome:"Welcome"}

đến:

{"welcome":"Welcome"}

1
Điều này không quan trọng trừ khi khóa là một từ dành riêng trong JS. Tôi không thấy đây là vấn đề ở đây.
John Gibb

1
JSON.opesify ({welcome: "Chào mừng"}) -> {"welcome": "Chào mừng"}
Thicesiram

5

Tôi tin rằng trình xử lý phản hồi Ajax sử dụng mã trạng thái HTTP để kiểm tra xem có lỗi hay không.

Vì vậy, nếu bạn chỉ ném một ngoại lệ Java vào mã phía máy chủ của mình nhưng sau đó phản hồi HTTP không có mã trạng thái 500 jQuery (hoặc trong trường hợp này có lẽ là XMLHttpRequest đối tượng ) sẽ cho rằng mọi thứ đều ổn.

Tôi đang nói điều này bởi vì tôi gặp vấn đề tương tự trong ASP.NET khi tôi đang ném thứ gì đó giống như ArgumentException ("Không biết phải làm gì ...") nhưng trình xử lý lỗi không kích hoạt.

Sau đó, tôi đặt thành Response.StatusCode500 hoặc 200 cho dù tôi có lỗi hay không.


5

jQuery.parseJSON rất hữu ích cho sự thành công và lỗi.

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

5

Bạn có một đối tượng JSON của ngoại lệ được ném, trong đối tượng xhr. Chỉ dùng

alert(xhr.responseJSON.Message);

Đối tượng JSON hiển thị hai thuộc tính khác: 'ExceptionType' và 'StackTrace'


5

Về cơ bản, hàm này tạo khóa API ngẫu nhiên duy nhất và trong trường hợp nếu nó không xuất hiện thì hộp thoại bật lên với thông báo lỗi xuất hiện

Trong trang Xem:

<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>

Từ bộ điều khiển:

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

Tham số gọi lại tùy chọn chỉ định chức năng gọi lại để chạy khi phương thức load () hoàn thành. Hàm gọi lại có thể có các tham số khác nhau:

Loại: Hàm (jqXHR jqXHR, Chuỗi textStatus, Chuỗi errorThrown)

Một chức năng được gọi nếu yêu cầu không thành công. Hàm nhận được ba đối số: Đối tượng jqXHR (trong jQuery 1.4.x, XMLHttpRequest), một chuỗi mô tả loại lỗi xảy ra và một đối tượng ngoại lệ tùy chọn, nếu xảy ra. Các giá trị có thể có cho đối số thứ hai (ngoài null) là "hết thời gian", "lỗi", "hủy bỏ" và "trình phân tích cú pháp". Khi xảy ra lỗi HTTP, errorThrown nhận phần văn bản của trạng thái HTTP, chẳng hạn như "Không tìm thấy" hoặc "Lỗi máy chủ nội bộ". Kể từ jQuery 1.5, cài đặt lỗi có thể chấp nhận một loạt các hàm. Mỗi chức năng sẽ được gọi lần lượt. Lưu ý: Trình xử lý này không được gọi cho các yêu cầu JSONP tên miền chéo và tên miền chéo.


4
$("#save").click(function(){
    $("#save").ajaxError(function(event,xhr,settings,error){
        $(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
    });
});

3

Ném một ngoại lệ mới trên máy chủ bằng cách sử dụng:

Phản hồi.StatusCode = 500

Phản hồi.StatusDescrip = ex.Message ()

Tôi tin rằng Mô tả Status được trả về cuộc gọi Ajax ...

Thí dụ:

        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

2

Mặc dù đã nhiều năm kể từ khi câu hỏi này được hỏi, tôi vẫn không tìm thấy xhr.responseTextcâu trả lời mình đang tìm kiếm. Nó trả về cho tôi chuỗi theo định dạng sau:

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

mà tôi chắc chắn không muốn hiển thị cho người dùng. Những gì tôi đang tìm kiếm là một cái gì đó như dưới đây:

alert(xhr.responseJSON.message);

xhr.responseJSON.message cung cấp cho tôi thông báo chính xác từ Đối tượng Json có thể hiển thị cho người dùng.


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

Nếu có bất kỳ hình thức được gửi với xác nhận

chỉ cần sử dụng phần còn lại của mã

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

... ... });


0

Trước tiên, chúng ta cần đặt <serviceDebug includeExceptionDetailInFaults = "True" /> trong web.config:

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

Ngoài ra, ở cấp độ jquery trong phần lỗi, bạn cần phân tích phản hồi lỗi có chứa ngoại lệ như:

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

Sau đó, sử dụng r.Message bạn có thể hiển thị văn bản ngoại lệ.

Kiểm tra mã hoàn chỉnh: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.