การจัดการข้อผิดพลาด jQuery Ajax แสดงข้อความยกเว้นที่กำหนดเอง


727

มีวิธีที่ฉันสามารถแสดงข้อความยกเว้นที่กำหนดเองเป็นการแจ้งเตือนในข้อความแสดงข้อผิดพลาด jQuery AJAX ของฉันหรือไม่

ตัวอย่างเช่นถ้าฉันต้องการส่งข้อยกเว้นทางฝั่งเซิร์ฟเวอร์ผ่านStrutsโดยthrow new ApplicationException("User name already exists");ฉันต้องการจับข้อความนี้ ('ชื่อผู้ใช้มีอยู่แล้ว') ในข้อความแสดงข้อผิดพลาด 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);
      }
    });
  }
});

ในการแจ้งเตือนครั้งที่สองที่ฉันแจ้งเตือนข้อผิดพลาดการโยนฉันได้รับundefinedและรหัสสถานะคือ 500

ฉันไม่แน่ใจว่าฉันจะไปไหนผิด ฉันจะแก้ไขปัญหานี้ได้อย่างไร

คำตอบ:


357

ตรวจสอบให้แน่ใจว่าคุณตั้งค่าResponse.StatusCodeเป็นอย่างอื่นที่ไม่ใช่ 200 เขียนข้อความข้อยกเว้นโดยใช้Response.Writeจากนั้นใช้ ...

xhr.responseText

.. ในจาวาสคริปต์ของคุณ


9
นี่ยังคงเป็นวิธีที่ถูกต้องในการทำเช่นนี้หลังจาก 2 ปีครึ่ง ... :) ฉันไปไกลกว่านี้และส่งคืนข้อผิดพลาดวัตถุ JSON ของฉันเองที่สามารถจัดการข้อผิดพลาดเดียวหรือหลายข้อได้ค่อนข้างดีสำหรับการตรวจสอบรูปแบบฝั่งเซิร์ฟเวอร์
AlexCode

@Wilson มันเป็นไปตามที่แสดงในคำตอบอันดับสูงอื่น ๆ ที่นี่
Sprintstar

3
ตอนนี้ฉันอยู่ในปี 2014 JSON เป็นยุคที่มีอิทธิพล xhr.responseJSONการใช้งานดังนั้นฉัน : D
Ravi

5
xhr.responseJSON จะถูกตั้งค่าหากคุณมั่นใจว่ามีการตั้งค่าเมตา (เช่น "Content-type: application / json") นั่นเป็นปัญหาที่ฉันเพิ่งพบ responseText ถูกตั้งค่าไว้ - responseJSON ไม่ใช่
อิกอร์

217

ควบคุม:

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

ดูสคริปต์:

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

13
นี่ไม่ใช่คำตอบที่ "ถูกต้อง" สำหรับคำถามนี้ แต่แน่นอนที่สุดจะแสดงวิธีแก้ปัญหาระดับที่สูงขึ้น ... Nice!
Ryan Anderson

3
ฉันกำลังทำสิ่งที่คล้ายกัน มันทำงานได้ดีถ้าทำทุกอย่างในกล่องพัฒนา หากฉันลองเชื่อมต่อจากกล่องอื่นบนเครือข่าย xhr.responseText มีหน้าข้อผิดพลาดทั่วไป html และไม่ใช่ข้อความที่กำหนดเองของฉันดูstackoverflow.com/questions/3882752/ …
jamiebarrow

6
ฉันเชื่อว่าคุณควรเพิ่มการตอบสนองสถานะ = 500; บรรทัดวิธี OnException
Alexander Prokofyev

4
ฉันดัดแปลงสิ่งนี้ - เนื่องจากฉันต้องการรหัสสถานะ 500 แต่มีข้อความข้อยกเว้นในคำอธิบายสถานะ (แทนที่จะ "ข้อผิดพลาดเซิร์ฟเวอร์ภายใน") - response.StatusCode = (int)HttpStatusCode.InternalServerError;และresponse.StatusDescription = filterContext.Exception.Message;
Kram

4
หากคุณใช้ IIS7 ขึ้นไปคุณอาจต้องเพิ่ม: response.TrySkipIisCustomErrors = true
James Gaunt

97

เซิร์ฟเวอร์:

     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

           }
 }

ด้านลูกค้า:

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

การจัดการข้อผิดพลาด Ajax ทั่วไป

หากฉันต้องจัดการข้อผิดพลาดทั่วไปสำหรับคำขอ ajax ทั้งหมด ฉันจะตั้งค่าตัวจัดการ ajaxError และแสดงข้อผิดพลาดใน div ชื่อ errorcontainer ที่ด้านบนของเนื้อหา 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

คุณต้องแปลงเป็นresponseTextJSON ใช้ JQuery:

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

5
+1 เพราะในขณะนี้คำตอบที่ถูกต้องสำหรับคำถามนี้คือในปัจจุบัน! คุณสามารถเรียก "jsonValue.Message" เพื่อรับข้อความแสดงข้อยกเว้น
Captain Sensible

2
จริงๆแล้วมันไม่ใช่คำตอบที่ถูกต้องเพราะคำถามไม่ได้ถามเกี่ยวกับ JSON และคำขอตัวอย่างนั้นขอให้ HTML ตอบเป็นการเฉพาะ
SingleShot

+1 ถูกต้อง หมายเหตุเป็นเรื่องปกติที่จะส่งวัตถุที่เข้ารหัส JSON ผ่าน jqXHR.responseText (สตริง) คุณสามารถใช้ jsonValue Object ได้ตามที่คุณต้องการ ใช้คอนโซล Firebug เพื่อตรวจสอบการตอบสนองโดยใช้ console.log (jsonValue)
jjwdesign

สิ่งนี้ทำให้ฉัน 'Uncaught SyntaxError: หมายเลขที่ไม่คาดคิด'
Ben Racicot

1
อ็อบเจ็กต์ JSON ที่วิเคราะห์คำถูกทำให้พร้อมใช้งานผ่านคุณสมบัติ responseJSON ของอ็อบเจ็กต์ jqXHR ดังนั้นไม่จำเป็นต้องแยกวิเคราะห์คุณสมบัติ ResponseText คุณสามารถทำได้: console.log (jqXHR.responseJSON.Message)
Eric D'Souza

37

หากทำการโทรไปที่ asp.net สิ่งนี้จะส่งคืนชื่อข้อความแสดงข้อผิดพลาด:

ฉันไม่ได้เขียน 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) ); 
})

22

นี่คือสิ่งที่ฉันทำและใช้งานได้ในแอปพลิเคชัน MVC 5

ชนิดส่งคืนของตัวควบคุมคือ 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"};
}

และในฝั่งไคลเอ็นต์นี่คือสิ่งที่ฟังก์ชั่น 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

หากมีใครบางคนอยู่ที่นี่ในปี 2559 สำหรับคำตอบให้ใช้.fail()สำหรับการจัดการข้อผิดพลาดตามที่.error()ถูกปฏิเสธเมื่อเป็น jQuery 3.0

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

ฉันหวังว่ามันจะช่วย


2
jqXHR.error()เลิกใช้แล้ว (ถูกลบออกจริง) ใน jQuery 3.0 แต่errorและการsuccessเรียกกลับไป$.ajax()ยังไม่เลิกใช้เท่าที่ฉันรู้
Neil Conway

16

โซลูชันทั่วไป / นำกลับมาใช้ซ้ำได้

คำตอบนี้มีไว้สำหรับอ้างอิงในอนาคตสำหรับผู้ที่เจอปัญหานี้ โซลูชันประกอบด้วยสองสิ่ง:

  1. ข้อยกเว้นที่กำหนดเอง ModelStateExceptionที่เกิดขึ้นเมื่อการตรวจสอบความถูกต้องล้มเหลวบนเซิร์ฟเวอร์ (สถานะของแบบจำลองรายงานข้อผิดพลาดในการตรวจสอบความถูกต้องเมื่อเราใช้คำอธิบายประกอบข้อมูลและใช้พารามิเตอร์การดำเนินการที่ควบคุมตัวพิมพ์ที่แข็งแกร่ง)
  2. ตัวกรองข้อผิดพลาดการกระทำของตัวควบคุมที่กำหนดเอง HandleModelStateExceptionAttributeที่จับข้อยกเว้นที่กำหนดเองและส่งกลับสถานะข้อผิดพลาด HTTP กับข้อผิดพลาดสถานะของแบบจำลองในร่างกาย

นี่เป็นโครงสร้างพื้นฐานที่ดีที่สุดสำหรับการโทร jQuery Ajax เพื่อใช้ศักยภาพsuccessและerrorจัดการได้อย่างเต็มประสิทธิภาพ

รหัสฝั่งไคลเอ็นต์

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

รหัสฝั่งเซิร์ฟเวอร์

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

    // create new user because validation was successful
}

ปัญหาทั้งหมดมีรายละเอียดในโพสต์บล็อกนี้ซึ่งคุณสามารถค้นหารหัสทั้งหมดเพื่อเรียกใช้ในแอปพลิเคชันของคุณ


14

ฉันพบสิ่งนี้จะดีเพราะฉันสามารถแยกข้อความที่ฉันส่งจากเซิร์ฟเวอร์และแสดงข้อความที่เป็นมิตรกับผู้ใช้โดยไม่ต้อง 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);
      }
ในรหัสข้อผิดพลาด ajax ขอจับข้อผิดพลาดเชื่อมต่อระหว่างไคลเอนต์กับเซิร์ฟเวอร์หากคุณต้องการแสดงข้อความแสดงข้อผิดพลาดของแอปพลิเคชันของคุณส่งในขอบเขตความสำเร็จ

เช่น

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

นี่อาจเกิดจากชื่อฟิลด์ JSON ที่ไม่มีเครื่องหมายคำพูด

เปลี่ยนโครงสร้าง JSON จาก:

{welcome:"Welcome"}

ถึง:

{"welcome":"Welcome"}

1
สิ่งนี้ไม่สำคัญเว้นแต่ว่าคีย์เป็นคำที่สงวนไว้ใน JS ฉันไม่เห็นว่านี่เป็นปัญหาที่นี่
John Gibb

1
JSON.stringify (ยินดีต้อนรับ: "ยินดีต้อนรับ"}) -> {"ยินดีต้อนรับ": "ยินดีต้อนรับ"}
Thulasiram

5

ฉันเชื่อว่าตัวจัดการการตอบสนอง Ajax ใช้รหัสสถานะ HTTP เพื่อตรวจสอบว่ามีข้อผิดพลาด

ดังนั้นถ้าคุณเพิ่งโยนข้อยกเว้น Java บนโค้ดฝั่งเซิร์ฟเวอร์ของคุณ แต่การตอบกลับ HTTP ไม่มีรหัสสถานะ 500 jQuery (หรือในกรณีนี้อาจเป็นวัตถุXMLHttpRequest ) จะถือว่าทุกอย่างเรียบร้อยดี

ฉันกำลังพูดถึงสิ่งนี้เพราะฉันมีปัญหาที่คล้ายกันใน ASP.NET ที่ฉันโยนบางสิ่งเช่น ArgumentException ("ไม่รู้ว่าจะทำอย่างไร ... ") แต่ตัวจัดการข้อผิดพลาดไม่เริ่มทำงาน

ฉันตั้งค่าเป็นResponse.StatusCode500 หรือ 200 ไม่ว่าฉันจะมีข้อผิดพลาดหรือไม่ก็ตาม


5

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

5

คุณมีวัตถุ JSON ของข้อยกเว้นที่ส่งออกมาในวัตถุ xhr เพียงแค่ใช้

alert(xhr.responseJSON.Message);

วัตถุ JSON เปิดเผยคุณสมบัติอื่นสอง: 'ExceptionType' และ 'StackTrace'


5

ฟังก์ชั่นนี้จะสร้างคีย์ API แบบสุ่มที่ไม่เหมือนใครและในกรณีที่มันไม่ปรากฏขึ้นในกล่องโต้ตอบพร้อมข้อความแสดงข้อผิดพลาด

ในหน้าดู:

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

จากตัวควบคุม:

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

พารามิเตอร์ตัวเลือกการโทรกลับระบุฟังก์ชั่นการโทรกลับที่จะทำงานเมื่อเสร็จสิ้นการโหลด () วิธีการ ฟังก์ชันการเรียกกลับสามารถมีพารามิเตอร์ต่างกัน:

ประเภท: ฟังก์ชั่น (jqXHR jqXHR, String textStatus, ข้อผิดพลาดสตริงโยน)

ฟังก์ชั่นที่จะเรียกว่าถ้าคำขอล้มเหลว ฟังก์ชั่นได้รับสามอาร์กิวเมนต์: วัตถุ jqXHR (ใน jQuery 1.4.x, XMLHttpRequest) สตริงที่อธิบายถึงประเภทของข้อผิดพลาดที่เกิดขึ้นและวัตถุข้อยกเว้นทางเลือกหากเกิดขึ้น ค่าที่เป็นไปได้สำหรับอาร์กิวเมนต์ที่สอง (นอกเหนือจาก null) คือ "หมดเวลา", "ข้อผิดพลาด", "ยกเลิก" และ "parsererror" เมื่อมีข้อผิดพลาด HTTP เกิดขึ้น errorThrown จะได้รับส่วนที่เป็นข้อความของสถานะ HTTP เช่น "Not Found" หรือ "Internal Server Error" ตั้งแต่ jQuery 1.5 การตั้งค่าข้อผิดพลาดสามารถยอมรับอาร์เรย์ของฟังก์ชันได้ ฟังก์ชั่นแต่ละอย่างจะถูกเรียกในทางกลับกัน หมายเหตุ: ตัวจัดการนี้ไม่ถูกเรียกใช้สำหรับสคริปต์ข้ามโดเมนและการร้องขอ JSONP ข้ามโดเมน



3

โยนข้อยกเว้นใหม่บนเซิร์ฟเวอร์โดยใช้:

Response.StatusCode = 500

Response.StatusDescription = ex.Message ()

ฉันเชื่อว่า StatusDescription ถูกส่งกลับไปยังการโทร Ajax ...

ตัวอย่าง:

        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

แม้ว่าจะเป็นเวลาหลายปีแล้วที่มีคนถามคำถามนี้ แต่ฉันก็ยังหาxhr.responseTextคำตอบไม่เจอ มันคืนสตริงให้ฉันในรูปแบบต่อไปนี้:

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

ซึ่งฉันไม่ต้องการแสดงให้ผู้ใช้เห็นอย่างแน่นอน สิ่งที่ฉันกำลังมองหามีดังนี้:

alert(xhr.responseJSON.message);

xhr.responseJSON.message ให้ข้อความที่แน่นอนจาก Json Object ซึ่งสามารถแสดงต่อผู้ใช้


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

หากมีรูปแบบใด ๆ ที่จะส่งด้วยการตรวจสอบ

เพียงใช้รหัสที่เหลือ

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

... ... });


0

ก่อนอื่นเราต้องตั้งค่า <serviceDebug includeExceptionDetailInFaults = "True" /> ใน web.config:

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

นอกจากนั้นในระดับ jquery ในส่วนของข้อผิดพลาดคุณต้องแยกวิเคราะห์การตอบสนองข้อผิดพลาดที่มีข้อยกเว้นเช่น:

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

จากนั้นใช้ r.Message คุณสามารถแสดงข้อความข้อยกเว้นได้

ตรวจสอบรหัสที่สมบูรณ์: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.