请注意,以下答案基于以下版本:
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 http://jsonapi.org/format/#error-objects
您会注意到,API 仅指定在由以下键控的顶级数组中返回错误errors
所有其他错误属性都是可选的。看来 JSON API 所需的全部内容如下:
{
"errors": [
{}
]
}
当然,这不会真正做任何事情,因此为了使 Ember Data 和 JSONAPIAdapter 的错误能够开箱即用,您至少需要包含detail
属性和source.pointer
属性。这detail
属性是设置为错误消息和source.pointer
attribute 让 Ember Data 找出模型中的哪个属性导致了问题。因此,Ember Data 所需的有效 JSON API 错误对象(如果您使用的是现在默认的 JSONAPI)如下所示:
{
"errors": [
{
"detail": "The attribute `is-admin` is required",
"source": {
"pointer": "data/attributes/is-admin"
}
}
]
}
注意detail
不是复数(对我来说是一个常见的错误),source.pointer
不应包含前导正斜杠,并且属性名称应采用破折号。
最后,您必须使用 HTTP 代码返回验证错误422
这意味着“不可处理的实体”。如果您不返回422
代码,那么默认情况下 Ember Data 将返回一个AdapterError
并且不会在模型上设置错误消息errors
哈希。这让我困惑了一段时间,因为我使用的是 HTTP 代码400
(错误请求)向客户端返回验证错误。
ember 数据区分两种类型错误的方式是验证错误返回一个InvalidError
目的 (http://emberjs.com/api/data/classes/DS.InvalidError.html http://emberjs.com/api/data/classes/DS.InvalidError.html)。这将导致errors
要设置的模型上的哈希值,但不会设置isError
标记为 true (不确定为什么会出现这种情况,但记录如下:http://emberjs.com/api/data/classes/DS.Model.html#property_isError http://emberjs.com/api/data/classes/DS.Model.html#property_isError)。默认情况下,HTTP 错误代码不是422
将导致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"
}
]
本质上detail
被映射到message
and source.pointer
被映射到attribute
。如果单个属性出现多个验证错误,则会返回一个数组(JSON API 允许您返回多个验证错误,而不是仅返回第一个失败的验证)。您可以直接在模板中使用错误值,如下所示:
{{#each model.errors.isAdmin as |error|}}
<div class="error">
{{error.message}}
</div>
{{/each}}
如果没有错误,那么上面的内容将不会显示任何内容,因此它非常适合执行表单验证消息。
如果您的 API 不使用 HTTP422
验证错误的代码(例如,如果它使用400
)然后您可以通过覆盖来更改 JSONAPIAdapter 的默认行为handleResponse
自定义适配器中的方法。这是一个返回新值的示例InvalidError
任何 HTTP 响应状态代码的对象400
.
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 错误并将消息放入模型上的错误哈希中)。