jQuery Ajax обробка помилок, показувати власні повідомлення про виключення


727

Чи я можу відображати власні повідомлення про виключення як попередження у своєму повідомленні про помилку jQuery AJAX?

Наприклад, якщо я хочу перенести виняток на сторону сервера через Struts by 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

..у вашому javascript.


9
Це все-таки правильний спосіб зробити це через 2 з половиною роки ... :) Я пішов трохи далі і фактично повертаю власну помилку об'єкта JSON, який може обробляти одиночні або декілька помилок, що дуже добре для перевірки форми на стороні сервера.
AlexCode

@Wilson Це було так, як показано в інших відповідях на високо оцінені тут.
Спринтстар

3
Я зараз у 2014 році. Домінував JSON. Так я використовую xhr.responseJSON. : D
Раві

5
xhr.responseJSON встановлюється лише в тому випадку, якщо ви переконаєтесь, що мета-тип встановлений (наприклад, "Тип вмісту: application / json"). Це проблема, з якою я щойно стикався; було встановлено responseText - відповідьJSON не було.
Ігор

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
Це не "правильна" відповідь на питання, але це, безумовно, показує рішення проблеми вищого рівня ... Приємно!
Райан Андерсон

3
Я роблю щось подібне. Це добре працює, якщо все зроблено на коробці розробки. Якщо я намагаюся підключенням з іншого вікна на мережу, xhr.responseText містить загальну сторінку помилки HTML , а не моє власне повідомлення, див stackoverflow.com/questions/3882752 / ...
jamiebarrow

6
Я вважаю, що ви також повинні додати response.StatusCode = 500; рядок до методу OnException
Олександр Прокоф’єв

4
Я адаптував це - оскільки хотів 500 код коду статусу, але мати повідомлення про виключення в описі статусу (а не "Внутрішня помилка сервера") - response.StatusCode = (int)HttpStatusCode.InternalServerError;таresponse.StatusDescription = filterContext.Exception.Message;
Крам

4
Якщо ви використовуєте IIS7 або вище, можливо, вам потрібно буде додати: response.TrySkipIisCustomErrors = true;
Джеймс Гонт

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

Загальне поводження з помилками Ajax

Якщо мені потрібно зробити якусь загальну обробку помилок для всіх запитів ajax. Я встановлю обробник ajaxError і відображуватиме помилку на діві з назвою 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

Вам потрібно перетворити responseTextна JSON. Використання JQuery:

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

5
+1, тому що це наразі єдина ПРАВИЛЬНА відповідь на це питання! Ви можете зателефонувати "jsonValue.Message", щоб отримати повідомлення про виключення.
Капітан Чутливий

2
Насправді це не правильна відповідь, оскільки питання не задається питанням JSON, а приклад запиту спеціально запитує HTML як відповідь.
SingleShot

+1 Правильно. Зауважте, звичайно надсилати кодований JSON об'єкт через jqXHR.responseText (рядок). Потім ви можете використовувати об’єкт jsonValue, як вам потрібно. Використовуйте консоль 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

Якщо хтось тут, як у 2016 році, для відповіді, використовуйте .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()не засуджується, наскільки я знаю.
Ніл Конвей

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

Я вважаю це приємним, тому що я міг розібрати повідомлення, яке я надсилав із сервера, і відобразити дружнє повідомлення користувачеві без тракту ...

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. Я не бачу в цьому проблеми.
Джон Гібб

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

5

Я вважаю, що обробник відповіді Ajax використовує код статусу HTTP, щоб перевірити, чи була помилка.

Отже, якщо ви просто кинете виняток Java на код вашого сервера, але тоді відповідь HTTP не має коду статусу 500, jQuery (або, можливо, у цьому випадку об'єкт XMLHttpRequest ) просто припустить, що все було добре.

Я говорю це, тому що в ASP.NET у мене була подібна проблема, куди я кидав щось на кшталт ArgumentException ("Не знаю, що робити ..."), але обробник помилок не запускав.

Потім я встановив Response.StatusCodeзначення 500 або 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));
}

Необов'язковий параметр зворотного виклику визначає функцію зворотного виклику, яку потрібно запустити після завершення методу load (). Функція зворотного дзвінка може мати різні параметри:

Тип: Функція (jqXHR jqXHR, String textStatus, String errorThrown)

Функція, яку потрібно викликати, якщо запит не працює. Функція отримує три аргументи: об’єкт jqXHR (в jQuery 1.4.x, XMLHttpRequest), рядок, що описує тип помилки, що виникає, і необов'язковий об'єкт виключення, якщо такий стався. Можливими значеннями другого аргументу (крім нульового) є "timeout", "error", "abort" та "parsererror". Коли виникає помилка HTTP, errorThrown отримує текстову частину статусу HTTP, наприклад "Не знайдено" або "Помилка внутрішнього сервера". Станом на jQuery 1.5, налаштування помилок може приймати масив функцій. Кожна функція буде викликана по черзі. Примітка: Цей обробник не викликається для міждоменного скрипту та міждоменних запитів JSONP.


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

3

Накиньте новий виняток на сервері, використовуючи:

Response.StatusCode = 500

Response.StatusDescription = ex.Message ()

Я вважаю, що опис статусу повертається до виклику 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, яке можна показати користувачам.


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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.