penanganan kesalahan jQuery Ajax, tampilkan pesan pengecualian khusus

728

Apakah ada cara saya bisa menampilkan pesan pengecualian khusus sebagai peringatan di pesan kesalahan jQuery AJAX saya?

Misalnya, jika saya ingin melempar pengecualian di sisi server melalui Struts oleh throw new ApplicationException("User name already exists");, saya ingin menangkap pesan ini ('nama pengguna sudah ada') di pesan kesalahan 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);
      }
    });
  }
});

Pada peringatan kedua, saat saya mengingatkan kesalahan yang terjadi, saya mendapatkan undefineddan kode statusnya adalah 500.

Saya tidak yakin di mana saya salah. Apa yang bisa saya lakukan untuk memperbaiki masalah ini?

Roman C
sumber

Jawaban:

357

Pastikan Anda menetapkan Response.StatusCodesesuatu selain 200. Tulis pesan pengecualian Anda menggunakan Response.Write, lalu gunakan ...

xhr.responseText

..di javascript Anda.

Sprintstar
sumber
9
Ini masih cara yang benar untuk melakukan ini setelah 2 tahun setengah ... :) Saya melangkah lebih jauh dan benar-benar mengembalikan kesalahan saya sendiri objek JSON yang dapat menangani kesalahan tunggal atau ganda, cukup bagus untuk validasi formulir sisi-server.
AlexCode
@ Willson Seperti yang ditunjukkan pada jawaban berperingkat tinggi lainnya di sini.
Sprintstar
3
Sekarang di 2014. Era JSON mendominasi. Jadi saya gunakan xhr.responseJSON. : D
Ravi
5
xhr.responseJSON hanya disetel jika Anda memastikan, bahwa tipe meta diatur (mis. "Tipe konten: aplikasi / json"). Itu masalah yang baru saja saya temui; responseText diatur - responseJSON tidak.
Igor
217

Pengendali:

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

Lihat skrip:

$.ajax({
    type: "post", url: "/SomeController/SomeAction",
    success: function (data, text) {
        //...
    },
    error: function (request, status, error) {
        alert(request.responseText);
    }
});
AlexMAS
sumber
13
Ini bukan jawaban yang "benar" untuk pertanyaan itu tetapi pasti menunjukkan solusi tingkat yang lebih tinggi untuk masalah ... Bagus!
Ryan Anderson
3
Saya melakukan hal serupa. Ini berfungsi dengan baik jika semuanya dilakukan pada kotak pengembangan. Jika saya mencoba menghubungkan dari kotak yang berbeda di jaringan, xhr.responseText berisi html halaman kesalahan umum dan bukan pesan khusus saya, lihat stackoverflow.com/questions/3882752/…
jamiebarrow
6
Saya percaya Anda juga harus menambahkan response.StatusCode = 500; line ke metode OnException.
Alexander Prokofyev
4
Saya mengadaptasi ini - karena saya ingin kode status 500, tetapi untuk memiliki pesan pengecualian dalam deskripsi status (bukan "Kesalahan server internal") - response.StatusCode = (int)HttpStatusCode.InternalServerError;danresponse.StatusDescription = filterContext.Exception.Message;
Kram
4
Jika Anda menggunakan IIS7 atau lebih baru, Anda mungkin perlu menambahkan: response.TrySkipIisCustomErrors = true;
James Gaunt
97

Sisi server:

     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

           }
 }

Sisi klien:

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

Penanganan Kesalahan Ajax Umum

Jika saya perlu melakukan beberapa penanganan kesalahan umum untuk semua permintaan ajax. Saya akan mengatur ajaxError handler dan menampilkan kesalahan pada div bernama errorcontainer di bagian atas konten 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);
                 });
Sanjeev Kumar Dangi
sumber
81

Anda perlu mengonversikan responseTextke JSON. Menggunakan JQuery:

jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);
Sydney
sumber
5
+1 karena sekarang ini satu-satunya jawaban yang BENAR untuk pertanyaan ini! Anda dapat memanggil "jsonValue.Message" untuk mendapatkan pesan pengecualian.
Kapten Sensible
2
Sebenarnya ini bukan jawaban yang benar karena pertanyaannya tidak menanyakan tentang JSON dan permintaan contoh secara khusus meminta HTML sebagai jawabannya.
SingleShot
+1 Benar. Catatan, Adalah umum untuk mengirim objek yang dikodekan JSON melalui jqXHR.responseText (string). Anda kemudian dapat menggunakan Object jsonValue seperti yang Anda butuhkan. Gunakan Firebug console untuk meninjau respons menggunakan console.log (jsonValue).
jjwdesign
Ini memberi saya 'Uncaught SyntaxError: Unexpected number'
Ben Racicot
1
Objek JSON yang diuraikan tersedia melalui properti responseJSON objek jqXHR. Jadi tidak perlu mem-parsing properti responseText. Anda bisa melakukannya: console.log (jqXHR.responseJSON.Message)
Eric D'Souza
37

Jika melakukan panggilan ke asp.net, ini akan mengembalikan judul pesan kesalahan:

Saya tidak menulis sendiri semua formatErrorMessage tetapi saya merasa sangat berguna.

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) ); 
})
Sam Jones
sumber
22

Inilah yang saya lakukan dan berfungsi sejauh ini dalam aplikasi MVC 5.

Jenis kembali pengontrol adalah 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"};
}

Dan di sisi klien inilah fungsi ajax terlihat

$.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;
    }
});
Cengiz Araz
sumber
20

Jika seseorang ada di sini pada 2016 untuk jawabannya, gunakan .fail()untuk penanganan kesalahan seperti .error()sudah usang pada jQuery 3.0

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

Saya harap ini membantu

Pelajar
sumber
2
jqXHR.error()sudah usang (sebenarnya dihapus) di jQuery 3.0, tetapi errordan successcallback $.ajax()tidak ditinggalkan, sejauh yang saya tahu.
Neil Conway
16

Solusi umum / dapat digunakan kembali

Jawaban ini disediakan untuk referensi di masa mendatang untuk semua orang yang menabrak masalah ini. Solusi terdiri dari dua hal:

  1. Pengecualian khusus ModelStateException yang dilemparkan ketika validasi gagal di server (status model melaporkan kesalahan validasi ketika kami menggunakan anotasi data dan menggunakan parameter aksi pengontrol yang diketik dengan kuat)
  2. Filter kesalahan aksi pengontrol khusus HandleModelStateExceptionAttribute yang menangkap pengecualian khusus dan mengembalikan status kesalahan HTTP dengan kesalahan status model di tubuh

Ini menyediakan infrastruktur optimal untuk panggilan jQuery Ajax untuk menggunakan potensi penuh successdan errorpenangannya.

Kode sisi klien

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

Kode sisi server

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

    // create new user because validation was successful
}

Seluruh masalah dirinci dalam posting blog ini di mana Anda dapat menemukan semua kode untuk menjalankan ini di aplikasi Anda.

Robert Koritnik
sumber
14

Saya menemukan ini bagus karena saya dapat mengurai pesan yang saya kirim dari server dan menampilkan pesan yang ramah kepada pengguna tanpa stacktrace ...

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

 error:function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }
dalam kesalahan kode, permintaan ajax untuk menangkap kesalahan terhubung antara klien ke server jika Anda ingin menampilkan pesan kesalahan dari aplikasi Anda mengirim dalam lingkup keberhasilan

seperti

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

}

Wara Haii
sumber
7

Ini mungkin disebabkan oleh nama bidang JSON yang tidak memiliki tanda kutip.

Ubah struktur JSON dari:

{welcome:"Welcome"}

untuk:

{"welcome":"Welcome"}
Orang
sumber
1
Ini seharusnya tidak masalah kecuali kuncinya adalah kata yang dilindungi undang-undang di JS. Saya tidak melihat ini menjadi masalah di sini.
John Gibb
1
JSON.stringify ({welcome: "Welcome"}) -> {"welcome": "Welcome"}
Thulasiram
5

Saya percaya penangan respons Ajax menggunakan kode status HTTP untuk memeriksa apakah ada kesalahan.

Jadi jika Anda hanya melempar pengecualian Java pada kode sisi server Anda tetapi kemudian respons HTTP tidak memiliki kode status 500 jQuery (atau dalam hal ini mungkin objek XMLHttpRequest ) hanya akan menganggap bahwa semuanya baik-baik saja.

Saya mengatakan ini karena saya punya masalah yang sama di ASP.NET di mana saya melempar sesuatu seperti ArgumentException ("Tidak tahu harus berbuat apa ...") tetapi penangan kesalahan tidak menembak.

Saya kemudian mengatur Response.StatusCodeke 500 atau 200 apakah saya memiliki kesalahan atau tidak.

Vitor Silva
sumber
5

jQuery.parseJSON berguna untuk kesuksesan dan kesalahan.

$.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); }
});
Nuri YILMAZ
sumber
5

Anda memiliki objek JSON dari pengecualian yang dilemparkan, di objek xhr. Gunakan saja

alert(xhr.responseJSON.Message);

Objek JSON mengekspos dua properti lainnya: 'ExceptionType' dan 'StackTrace'

Edika
sumber
5

Fungsi ini pada dasarnya menghasilkan kunci API acak unik dan dalam kasus jika tidak maka kotak dialog pop-up dengan pesan kesalahan muncul

Di Halaman Tampilan:

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

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

Parameter panggilan balik opsional menentukan fungsi panggilan balik untuk dijalankan ketika metode load () selesai. Fungsi panggilan balik dapat memiliki parameter yang berbeda:

Tipe: Fungsi (jqXHR jqXHR, String textStatus, String errorThrown)

Suatu fungsi untuk dipanggil jika permintaan gagal. Fungsi menerima tiga argumen: Objek jqXHR (dalam jQuery 1.4.x, XMLHttpRequest), string yang menjelaskan jenis kesalahan yang terjadi dan objek pengecualian opsional, jika terjadi. Nilai yang mungkin untuk argumen kedua (selain nol) adalah "batas waktu", "kesalahan", "batalkan", dan "parsererror". Ketika kesalahan HTTP terjadi, errorThrown menerima bagian tekstual dari status HTTP, seperti "Tidak Ditemukan" atau "Kesalahan Server Internal." Pada jQuery 1.5, pengaturan kesalahan dapat menerima berbagai fungsi. Setiap fungsi akan dipanggil secara bergantian. Catatan: Handler ini tidak dipanggil untuk permintaan lintas domain dan permintaan JSONP lintas-domain.

Nɪsʜᴀɴᴛʜ ॐ
sumber
4
$("#save").click(function(){
    $("#save").ajaxError(function(event,xhr,settings,error){
        $(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
    });
});
ibrahim ozboluk
sumber
3

Lempar pengecualian baru di server menggunakan:

Response.StatusCode = 500

Response.StatusDescription = ex.Message ()

Saya percaya bahwa StatusDescription dikembalikan ke panggilan Ajax ...

Contoh:

        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
Steffan
sumber
2

Meskipun sudah bertahun-tahun sejak pertanyaan ini diajukan, saya masih belum menemukan xhr.responseTextjawaban yang saya cari. Ini mengembalikan saya string dalam format berikut:

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

yang saya jelas tidak ingin ditampilkan kepada pengguna. Apa yang saya cari adalah sesuatu seperti di bawah ini:

alert(xhr.responseJSON.message);

xhr.responseJSON.message memberi saya pesan yang tepat dari Objek Json yang dapat ditampilkan kepada pengguna.

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

Jika ada formulir kirimkan dengan validasi

cukup gunakan sisa kode

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

... ... });

Monzurum
sumber
0

Pertama kita perlu mengatur <serviceDebug includeExceptionDetailInFaults = "True" /> di web.config:

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

Selain itu pada tingkat jquery di bagian kesalahan Anda perlu mengurai respons kesalahan yang berisi pengecualian seperti:

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

Kemudian menggunakan r.Message Anda dapat menampilkan teks pengecualian secara penuh.

Periksa kode lengkap: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

Avinash
sumber