jQuery Ajax hata işleme, özel istisna mesajları göster


732

Özel istisna iletileri jQuery AJAX hata iletimde bir uyarı olarak gösterebilirim bir yolu var mı?

Örneğin, Struts by yoluyla sunucu tarafında bir istisna atmak throw new ApplicationException("User name already exists");istersem, jQuery AJAX hata iletisinde bu iletiyi ('kullanıcı adı zaten var') yakalamak istiyorum.

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

Atılan hatayı uyardığım ikinci uyarıda, alıyorum undefinedve durum kodu 500.

Nerede yanlış yaptığımdan emin değilim. Bu sorunu gidermek için ne yapabilirim?

Yanıtlar:


359

Response.StatusCode200 dışında bir ayar yaptığınızdan emin olun Response.Write.

xhr.responseText

... javascriptinizde.


9
Bu hala 2 yıl ve bir buçuk sonra bunu yapmanın doğru yolu ... :) Ben biraz daha ileri gitti ve aslında tek veya birden fazla hataları işleyebilir, sunucu tarafı form doğrulama için oldukça iyi kendi hata JSON nesnesi döndürür.
AlexCode

@Wilson Buradaki diğer yüksek puanlı cevaplarda gösterildiği gibiydi.
Sprintstar

3
Şimdi 2014'teyim. JSON dönemi domine etti. Bu yüzden kullanıyorum xhr.responseJSON. : D
Ravi

5
xhr.responseJSON yalnızca meta türün ayarlandığından emin olmanız durumunda ayarlanır (örn. "İçerik türü: application / json"). Bu yeni karşılaştığım bir sorun; responseText ayarlandı - responseJSON ayarlanmadı.
Igor

220

Denetleyici:

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

Komut dosyasını görüntüle:

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

13
Bu soruya "doğru" bir cevap değil ama kesinlikle soruna daha üst düzey bir çözüm gösteriyor ... Güzel!
Ryan Anderson

3
Benzer bir şey yapıyorum. Her şey geliştirme kutusunda yapılırsa iyi çalışır. Ağdaki farklı bir kutudan bağlanmaya çalışırsam, xhr.responseText özel mesajımı değil, genel hata sayfası html'yi içerir, bkz. Stackoverflow.com/questions/3882752/…
jamiebarrow 7:10

6
Ben de yanıt eklemek gerektiğini düşünüyorum.StatusCode = 500; OnException yöntemi satır.
Alexander Prokofyev

4
Bunu uyarladım - 500 durum kodunu istediğimden, ancak durum açıklamasında ("Dahili sunucu hatası" yerine) istisna iletisine sahip olduğum için - response.StatusCode = (int)HttpStatusCode.InternalServerError;veresponse.StatusDescription = filterContext.Exception.Message;
Kram

4
IIS7 veya üstünü kullanıyorsanız şunları eklemeniz gerekebilir: response.TrySkipIisCustomErrors = true;
James Gaunt

97

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

Genel Ajax Hata İşleme

Tüm ajax istekleri için bazı genel hata işleme yapmak gerekirse. AjaxError işleyicisini ayarlayacağım ve hatayı html içeriğinin üstünde errorcontainer adlı bir div üzerinde göstereceğim.

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

82

responseTextJSON'a dönüştürmeniz gerekir . JQuery kullanma:

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

5
+1 'çünkü bu şu anda bu sorunun tek doğru cevabı! İstisna mesajı almak için "jsonValue.Message" çağırabilirsiniz.
Kaptan Mantıklı

2
Aslında soru doğru cevap değildir çünkü soru JSON hakkında soru sormaz ve örnek istek özellikle HTML olarak yanıt ister.
SingleShot

+1 Doğru. Not, jqXHR.responseText (string) aracılığıyla JSON kodlu bir nesne göndermek yaygındır. Daha sonra jsonValue nesnesini nasıl kullanmanız gerektiğini kullanabilirsiniz. Console.log (jsonValue) kullanarak yanıtı incelemek için Firebug konsolunu kullanın.
jjwdesign

Bu bana 'Yakalanmamış
Sözdizimi Hatası

1
Ayrıştırılan JSON nesnesi, jqXHR nesnesinin responseJSON özelliği aracılığıyla kullanılabilir. Bu yüzden responseText özelliğini ayrıştırmaya gerek yoktur. Şunları yapabilirsiniz: console.log (jqXHR.responseJSON.Message)
Eric D'Souza

37

Bir asp.net çağrısı yapıyorsanız, bu hata mesajı başlığını döndürür:

Tüm formatErrorMessage'ı kendim yazmadım ama çok kullanışlı buluyorum.

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

Yaptığım şey bu ve şimdiye kadar bir MVC 5 uygulamasında çalışıyor.

Denetleyicinin dönüş türü ContentResult'tur.

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

Ve müşteri tarafında ajax işlevi böyle görünüyor

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

Birisi yanıt için 2016'da olduğu gibi, jQuery 3.0'dan itibaren kullanımdan kaldırılan .fail()hata işleme için kullanın.error()

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

Umut ediyorum bu yardım eder


2
jqXHR.error()jQuery 3.0'da kullanımdan kaldırılmıştır (aslında kaldırılmıştır), ancak errorve successgeri çağrıları $.ajax()bildiğim kadarıyla kullanımdan kaldırılmamıştır.
Neil Conway

16

Genel / tekrar kullanılabilir bir çözüm

Bu cevap, ileride bu sorunla karşılaşan herkese referans olması için verilmiştir. Çözüm iki şeyden oluşur:

  1. Sunucuda ModelStateException doğrulama başarısız olduğunda atılan özel kural dışı durum (veri durumu ek açıklamaları kullandığımızda ve güçlü yazılan denetleyici eylem parametreleri kullandığımızda model durumu doğrulama hataları bildiriyor)
  2. Özel HandleModelStateExceptionAttribute özel durumu yakalayan ve gövdede model durumu hatasıyla HTTP hata durumunu döndüren özel denetleyici eylem hatası filtresi

Bu, jQuery Ajax çağrıları ile successve errorişleyicilerin tüm potansiyelini kullanmak için en uygun altyapıyı sağlar .

İstemci tarafı kodu

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

Sunucu tarafı kodu

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

    // create new user because validation was successful
}

Tüm sorun, uygulamanızda bunu çalıştırmak için tüm kodu bulabileceğiniz bu blog gönderisinde ayrıntılıdır .


14

Sunucudan gönderdiğim mesajı ayrıştırabildiğim ve stacktrace olmadan kullanıcıya kolay bir mesaj gösterebildiğim için bunu iyi buldum ...

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

12

 error:function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }
kod hatası ajax yakalama hatası isteği, uygulamanızın hata mesajını göstermek istiyorsanız, başarı kapsamında göndermek istiyorsanız, sunucu ile istemci arasında bağlantı kurun

gibi

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

Bu muhtemelen JSON alan adlarında tırnak işareti bulunmamasından kaynaklanır.

JSON yapısını şununla değiştirin:

{welcome:"Welcome"}

için:

{"welcome":"Welcome"}

1
Anahtar JS'de ayrılmış bir sözcük olmadığı sürece bu önemli değildir. Bunun burada bir sorun olduğunu görmüyorum.
John Gibb

1
JSON.stringify ({welcome: "Welcome"}) -> {"welcome": "Welcome"}
Thulasiram

6

Xhr nesnesine atılan kural dışı durumun bir JSON nesnesi var. Sadece kullan

alert(xhr.responseJSON.Message);

JSON nesnesi iki özellik daha sunar: 'ExceptionType' ve 'StackTrace'


5

Ajax yanıt işleyicisi bir hata olup olmadığını kontrol etmek için HTTP durum kodunu kullanır inanıyorum.

Bu nedenle, sunucu tarafı kodunuza bir Java istisnası atarsanız, ancak HTTP yanıtında 500 durum kodu yoksa jQuery (veya bu durumda muhtemelen XMLHttpRequest nesnesi) her şeyin yolunda olduğunu varsayar.

Bunu ArgumentException ("ne yapacağımı bilmiyorum ...") gibi bir şey atmak ASP.NET benzer bir sorun vardı çünkü söylüyorum ama hata işleyicisi ateş değildi.

Sonra Response.StatusCodebir hata olsun ya da olmasın ben 500 veya 200 olarak ayarlayın .


5

jQuery.parseJSON, başarı ve hata için kullanışlıdır.

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

Bu işlev temel olarak benzersiz rastgele API anahtarları oluşturur ve bu durumda hata mesajı içeren bir iletişim kutusu görüntülenirse

Görünüm Sayfasında:

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

Denetleyiciden:

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

İsteğe bağlı geri arama parametresi, load () yöntemi tamamlandığında çalıştırılacak geri arama işlevini belirtir. Geri arama işlevinin farklı parametreleri olabilir:

Tür: İşlev (jqXHR jqXHR, String textStatus, String errorThrown)

İstek başarısız olursa çağrılacak bir işlev. İşlev üç bağımsız değişken alır: jqXHR (jQuery 1.4.x, XMLHttpRequest) nesnesi, oluşan hata türünü açıklayan bir dize ve varsa isteğe bağlı bir istisna nesnesi. İkinci bağımsız değişken için olası değerler (null dışında) "timeout", "error", "abort" ve "parsererror" dur. Bir HTTP hatası oluştuğunda errorThrown, HTTP durumunun "Bulunamadı" veya "Dahili Sunucu Hatası" gibi metinsel kısmını alır. JQuery 1.5 itibariyle, hata ayarı bir dizi işlevi kabul edebilir. Her fonksiyon sırayla çağrılır. Not: Bu işleyici, etki alanları arası komut dosyası ve etki alanları arası JSONP istekleri için çağrılmaz.


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

3

Sunucuda aşağıdakileri kullanarak yeni bir istisna atın:

Response.StatusCode = 500

Response.StatusDescription = ex.Message ()

StatusDescription öğesinin Ajax çağrısına döndüğüne inanıyorum ...

Misal:

        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

Bu sorunun sorulmasından bu yana uzun yıllar geçmesine rağmen xhr.responseText, aradığım cevap olarak hala bulamıyorum . Bana şu biçimde dizesini döndürdü:

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

ki bu kesinlikle kullanıcılara göstermek istemiyorum. Ne aradığım aşağıdaki gibi bir şey:

alert(xhr.responseJSON.message);

xhr.responseJSON.message bana Json Nesnesi'nden kullanıcılara gösterilebilen tam mesajı veriyor.


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

Doğrulanmış bir form gönderilirse

sadece kodun geri kalanını kullanın

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

... ... });


0

Öncelikle web.config içinde <serviceDebug includeExceptionDetailInFaults = "True" /> ayarlamamız gerekiyor:

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

Buna ek olarak, hata bölümünde jquery düzeyinde, aşağıdaki gibi istisna içeren hata yanıtını ayrıştırmanız gerekir:

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

Sonra r.Message kullanarak istisna metni aktüel olarak gösterebilirsiniz.

Kodun tamamını kontrol edin: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.