web-dev-qa-db-ja.com

(現在はデフォルト)Ember Data JSON-API adapter)でエラーを処理する

私はEmber 1.13.7およびEmber Data 1.13.8を使用しています。これらはデフォルトでJSON-API標準を使用して、送受信されるペイロードをフォーマットしますAPI。

Emberデータの組み込みエラー処理を使用して、ユーザーに赤い「エラー」フォームフィールドを表示します。JSON-API標準に従ってAPIエラー応答をフォーマットしました。例えば.

{"errors":[
    {
        "title":"The included.1.attributes.street name field is required.", 
        "code":"API_ERR", 
        "status":"400", 
    }
]}

モデルを保存しようとすると、エラーコールバックが正しく実行されます。 Ember Inspector内を見ると、モデルの "isError"値がtrueに設定されていることがわかりますが、Emberデータが想定されている方法がわかりませんモデル内のどのフィールドがエラー状態にあるかを知るには?公式JSON-APIページ( http://jsonapi.org/format/#errors )から、エラー応答内の「ソース」オブジェクト:

source:エラーのソースへの参照を含むオブジェクト。オプションで次のメンバーのいずれかを含めることができます。

ポインタ:リクエストドキュメント内の関連エンティティへのJSONポインタ[RFC6901] [例:プライマリデータオブジェクトの場合は「/ data」、特定の属性の場合は「/ data/attributes/title」。

parameter:エラーの原因となったクエリパラメータを示す文字列。

Emberデータにエラー状態であることをマークする必要のあるデータを伝えるために、これは何をすべきか?

誰かがこれについていくつかの光を当てるのを助けることができるならば、私は感謝するでしょう。

ありがとう。

22
danr1979

以下の回答は次のバージョンに基づいていることに注意してください。

DEBUG: -------------------------------
ember.debug.js:5442DEBUG: Ember                     : 1.13.8
ember.debug.js:5442DEBUG: Ember Data                : 1.13.9
ember.debug.js:5442DEBUG: jQuery                    : 1.11.3
DEBUG: -------------------------------

現時点では、さまざまなアダプタ(Active、REST、JSON)のエラーを処理する方法がすべて少し異なるため、エラー処理のドキュメントは現時点で散在しています。

あなたのケースでは、おそらく検証エラーを意味するフォームの検証エラーを処理する必要があります。 JSON APIで指定されているエラーの形式は次のとおりです。 http://jsonapi.org/format/#error-objects

APIは、errorsをキーとする最上位の配列でエラーが返されることのみを指定し、他のすべてのエラー属性はオプションであることに注意してください。したがって、JSON APIに必要なのは次のようです。

{
    "errors": [
     {}
    ]
}  

もちろん、実際には何もしないので、エラーがEmber DataとJSONAPIAdapterですぐに機能するようにするには、少なくともdetail属性とsource/pointer属性を含める必要があります。 detail属性は、エラーメッセージとして設定されるものであり、source/pointer属性は、モデルのどの属性が問題を引き起こしているのかをEmberデータが把握できるようにします。したがって、Emberデータで必要とされる有効なJSON APIエラーオブジェクト(現在はデフォルトとなっているJSONAPIを使用している場合)は次のようになります。

{
    "errors": [
     {
        "detail": "The attribute `is-admin` is required",
        "source": {
             "pointer": "data/attributes/is-admin"
         }
     }
    ]
}  

detailは複数形ではないことに注意してください(私にとってはよくある間違いです)、source/pointerの値には先頭にスラッシュを含めないでください。また、属性名はダッシュ化する必要があります。

最後に、HTTPコード422を使用して検証エラーを返す必要があります。これは、「処理できないエンティティ」を意味します。 422コードを返さない場合、デフォルトではEmberデータはAdapterErrorを返し、モデルのerrorsハッシュにエラーメッセージを設定しません。 HTTPコード400(不正なリクエスト)を使用して検証エラーをクライアントに返していたため、しばらくの間、これは私に少し噛み付きました。

emberデータが2つのタイプのエラーを区別する方法は、検証エラーがInvalidErrorオブジェクトを返すことです( http://emberjs.com/api/data/classes/DS.InvalidError.html )。これにより、モデルのerrorsハッシュが設定されますが、isErrorフラグはtrueに設定されません(これが原因であるかは不明ですが、ここに記載されています: http://emberjs.com/api/data /classes/DS.Model.html#property_isError )。デフォルトでは、422以外のHTTPエラーコードは、AdapterErrorが返され、isErrorフラグがtrueに設定されます。どちらの場合も、promiseの拒否ハンドラが呼び出されます。

model.save().then(function(){
    // yay! it worked
}, function(){
    // it failed for some reason possibly a Bad Request (400)
    // possibly a validation error (422)
}

デフォルトでは、返されるHTTPコードが422であり、正しいJSON APIエラー形式を持っている場合、ハッシュキーが属性名であるモデルのエラーハッシュにアクセスすることにより、エラーメッセージにアクセスできます。ハッシュは、キャメルケース形式の属性名に基づいています。

たとえば、上記のjson-apiエラーの例では、is-adminにエラーがある場合、次のようにそのエラーにアクセスします。

model.get('errors.isAdmin');

これは、次のような形式のエラーオブジェクトを含む配列を返します。

[
   {
      "attribute": "isAdmin",
      "message": "The attribute `is-admin` is required"
    }
]

基本的に、detailmessageにマップされ、source/pointerattributeにマップされます。単一の属性で複数の検証エラーが発生した場合は、配列が返されます(JSON APIを使用すると、失敗した最初の検証だけを返すのではなく、複数の検証エラーを返すことができます)。次のように、エラー値をテンプレートで直接使用できます。

{{#each model.errors.isAdmin as |error|}}
    <div class="error">
      {{error.message}}
    </div>
{{/each}}

エラーがない場合、上記は何も表示しないため、フォーム検証メッセージを実行するのに適しています。

APIが検証エラーにHTTP 422コードを使用しない場合(たとえば、400を使用する場合)、カスタムアダプターのhandleResponseメソッドをオーバーライドすることにより、JSONAPIAdapterのデフォルトの動作を変更できます。次に、400であるHTTP応答ステータスコードの新しいInvalidErrorオブジェクトを返す例を示します。

import DS from "ember-data";
import Ember from "ember";

export default DS.JSONAPIAdapter.extend({
  handleResponse: function(status, headers, payload){
    if(status === 400 && payload.errors){
      return new DS.InvalidError(payload.errors);
    }
    return this._super(...arguments);
  }
});

上記の例では、HTTPステータスが400かどうかを確認し、エラープロパティが存在することを確認しています。もしそうなら、私は新しいDS.InvalidErrorを作成してそれを返します。これにより、422 HTTPステータスコードを期待するデフォルトの動作と同じ動作になります(つまり、JSON APIエラーが処理され、メッセージがモデルのエラーハッシュに入れられます)。

お役に立てば幸いです。

87
Sarus