jQuery Ajaxエラー処理、カスタム例外メッセージを表示


728

カスタム例外メッセージを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);
      }
    });
  }
});

2番目のアラートでは、スローされたエラーをアラートしundefinedますが、ステータスコードは500です。

どこが悪いのかわかりません。この問題を解決するにはどうすればよいですか?

回答:


357

Response.StatusCode200以外に設定していることを確認してください。を使用して例外のメッセージを書き込んResponse.Writeでから、...を使用してください。

xhr.responseText

..あなたのjavascriptで。


9
これは、2年半後もこれを行う正しい方法です... :)少し進んで、実際に単一または複数のエラーを処理できる独自のエラーJSONオブジェクトを返します。サーバー側のフォーム検証に非常に適しています。
AlexCode

@Wilsonここの他の高評価の回答に示されているとおりでした。
Sprintstar 2014年

3
現在は2014年です。JSONが時代を支配しました。だから私は使用しますxhr.responseJSON。:D
Ravi

5
xhr.responseJSONは、メタタイプが設定されていることを確認した場合にのみ設定されます(例: "Content-type:application / json")。それが今遭遇した問題です。responseTextが設定されました-responseJSONは設定されませんでした。
イゴール2014

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メソッドへの行。
Alexander Prokofyev、2011

4
私はこれを採用しました-500ステータスコードが欲しかったので、(「内部サーバーエラー」ではなく)ステータスの説明に例外メッセージを含めるためです- response.StatusCode = (int)HttpStatusCode.InternalServerError;およびresponse.StatusDescription = filterContext.Exception.Message;
Kram

4
IIS7以降を使用している場合は、以下を追加する必要があります。response.TrySkipIisCustomErrors= true;
James Gaunt、2013年

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ハンドラーを設定し、エラーをhtmlコンテンツの上部にあるerrorcontainerという名前のdivに表示します。

$("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
これは現在、この質問に対する唯一の正しい回答であるためです。「jsonValue.Message」を呼び出して、例外メッセージを取得できます。
キャプテンSensible

2
質問はJSONについて尋ねておらず、サンプルリクエストは特に応答としてHTMLを求めているため、実際には正しい答えではありません。
SingleShot 2007

+1正解。注:jqXHR.responseText(文字列)を介してJSONエンコードされたオブジェクトを送信するのが一般的です。その後、必要に応じてjsonValueオブジェクトを使用できます。Firebugコンソールを使用し、console.log(jsonValue)を使用して応答を確認します。
jjwdesign 2013年

これは私に 'Uncaught
SyntaxError

1
解析されたJSONオブジェクトは、jqXHRオブジェクトのresponseJSONプロパティを介して利用できます。したがって、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年のように誰かがここにいる場合は、jQuery 3.0で非推奨になっている.fail()エラー処理に使用します.error()

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

一般的/再利用可能なソリューション

この回答は、この問題にぶつかるすべての人を将来参照するために提供されています。ソリューションは次の2つで構成されます。

  1. ModelStateExceptionサーバーで検証が失敗したときにスローされるカスタム例外(データアノテーションを使用し、厳密に型指定されたコントローラーアクションパラメーターを使用すると、モデルの状態が検証エラーを報告します)
  2. カスタム HandleModelStateExceptionAttribute例外をキャッチし、本文にモデル状態エラーを含むHTTPエラーステータスを返すカスタムコントローラーアクションエラーフィルター

これにより、jQuery Ajax呼び出しの最適なインフラストラクチャが提供されsuccesserrorハンドラーとの潜在能力を最大限に活用できます。

クライアントサイドコード

$.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( "Do n't know what ... to do ...")のようなものをスローしていたのにエラーハンドラーが起動しなかったという同様の問題があったからです。

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

xhrオブジェクトに、スローされた例外のJSONオブジェクトがあります。使うだけ

alert(xhr.responseJSON.Message);

JSONオブジェクトは、他の2つのプロパティ「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));
}

オプションのcallbackパラメータは、load()メソッドが完了したときに実行するコールバック関数を指定します。コールバック関数は異なるパラメーターを持つことができます:

タイプ:Function(jqXHR jqXHR、String textStatus、String errorThrown)

リクエストが失敗した場合に呼び出される関数。関数は3つの引数を受け取ります。jqXHR(jQuery 1.4.xではXMLHttpRequest)オブジェクト、発生したエラーのタイプを説明する文字列、およびオプションの例外オブジェクト(発生した場合)です。2番目の引数(null以外)の可能な値は、「timeout」、「error」、「abort」、および「parsererror」です。HTTPエラーが発生すると、errorThrownは「Not Found」や「Internal Server Error」などの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()

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オブジェクトからの正確なメッセージを私に与えます。


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

まず、web.configで<serviceDebug includeExceptionDetailInFaults = "True" />を設定する必要があります。

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