使用(现在默认)Ember Data JSON-API 适配器处理错误

2024-04-22

我使用的是 Ember 1.13.7 和 Ember Data 1.13.8,它们默认使用 JSON-API 标准来格式化发送到 API 和从 API 接收的有效负载。

我想使用 Ember Data 的内置错误处理来向用户显示红色“错误”表单字段。我已根据 JSON-API 标准格式化了我的 API 错误响应,例如

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

当我尝试保存模型时,错误回调正在正确执行。如果我查看 Ember 检查器,我可以看到模型的“isError”值设置为 true,但我看不到 Ember 数据应该如何知道模型中的哪个字段处于错误状态?我从官方 JSON-API 页面看到(http://jsonapi.org/format/#errors http://jsonapi.org/format/#errors)您可以在错误响应中包含“源”对象:

source:包含对错误源的引用的对象, 可选地包括以下任何成员:

指针:指向请求文档中关联实体的 JSON 指针 [RFC6901] [例如。 “/data”表示主数据对象,或“/data/attributes/title” 对于特定属性]。

参数:一个字符串,表示哪个查询 参数导致错误。

但这是我应该做的,以便告诉 Ember Data 哪些字段应该标记为处于错误状态?

如果有人能帮助阐明这一点,我将不胜感激。

Thanks.


请注意,以下答案基于以下版本:

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.pointerattribute 让 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并返回。这将导致与期望的默认行为相同的行为422HTTP 状态代码(即,将处理您的 JSON API 错误并将消息放入模型上的错误哈希中)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用(现在默认)Ember Data JSON-API 适配器处理错误 的相关文章

随机推荐

  • 如何渲染响应?

    我正在使用 render to response 将列表发送到模板 我正在使用 django 快捷方式 锄头要这么做吗 如何使用变量设置上下文实例 from django shortcuts import render to respons
  • C#:将设置导入文件/从文件导出设置

    从应用程序内将应用程序内部设置导入 导出到文件中的最佳方法是什么 我有 Settings settings 文件 与设置文件绑定的 winform UI 并且我想要导入 导出设置 类似于 Visual Studio 导入 导出设置功能 如果
  • 如何测试 ANT 中的目录是否为空?

    如何测试 ant 中的目录是否为空 您可以使用pathconvert http ant apache org manual Tasks pathconvert html任务来做到这一点 与setonempty财产
  • Lua中如何对数字表求和?

    Lua有内置的吗sum 功能 我似乎找不到一个 我几乎翻遍了文档中的所有地方 或许table sum 或类似的东西 以遵循当前的约定 但由于我找不到它 我不得不实现它 function sum t local sum 0 for k v i
  • Magento - 检查管理员和客户是否登录

    我有一个安装了 Magento 1 4 0 1 的 Web 服务器 我有另一个与之共享凭据的网站 我已经设法检查客户是否登录 在更改 Magento 中的 cookie 位置之后 但是当我还尝试确定管理员是否登录时 事情变得复杂 我只能得到
  • 当标题顺序更改时,带有状态保存的数据表过滤器会导致问题

    我有一个html页面和一些 javascript 代码 下面是我的工作html table class table table hover thead tr th class color white Employee ID th th cl
  • 检查用户是否是 SQL Server 中 dbo 角色的成员

    我需要一个 T SQL 语句来检查用户是否是 SQL Server 中数据库角色的成员 具体来说 我需要知道用户是否是 dbo 角色的成员 因为这样我就不必向该用户授予额外的权限 如果我尝试在用户为 dbo 时添加额外权限 则会失败 并且我
  • 在同一端口上支持 IPv6 和 IPv4 的 C# 服务器

    是否有可能有一个同时侦听和接受 IPv6 和 IPv4 客户端的 Socket 我在 C 中使用了 IPv6 套接字 希望它能自动向后兼容 但 IPv4 客户端会导致无效的 ip 地址异常 看一看 您可以接受 IPv4 客户端以及 IPv6
  • 有关如何部署 C++ 代码以在任何地方工作的提示

    我不是在谈论制作可移植代码 这更多的是一个分配问题 我有一个中型项目 它对常用库有几个依赖项 例如 openssl zlib 等 它在我的机器上编译得很好 现在是时候将它呈现给世界了 本质上是构建最好的工程 我想制作适用于 Windows
  • 当所有其他列都保证相同时,仅从 CSV 文件中读取选定的列

    我有一堆 CSV 文件 我试图将它们连接成一个 csv 文件 CSV 文件由一个空格分隔 如下所示 initial pos orientation ratio chr 106681 0 06 chr 106681 0 88 chr 1066
  • 选择 Haskell 解析器

    有很多开源的解析器实现 http hackage haskell org packages archive pkg list html cat parsing我们可以在 Haskell 中使用 Parsec http hackage has
  • 编辑就地 Swing 组件

    有谁知道 Swing 组件本质上是电子表格 允许就地编辑并且可以 以某种方式 绑定到数组 如果您不需要任何花哨的东西 您可以使用标准秋千JTable 参见例如here http download oracle com javase tuto
  • 子视图图层变换和布局Subviews

    我的问题与 UIView CALayer 变换触发超级视图中的layoutSubviews https stackoverflow com questions 24632876 uiview calayer transform trigge
  • 需要使 PowerShell 脚本更快

    我自学了 Powershell 所以我不知道它的一切 我需要搜索一个数据库 其中包含我输入的确切行数 数据库是预定义的 它包含 gt 11800 个条目 您能帮我找出是什么原因导致速度变慢吗 Code Dict Get Content C
  • 为什么 Selenium 有时会以安全模式启动 Firefox(用户无需按 Shift 键)?

    我正在使用 Firefox Selenium Web 驱动程序在专用测试机上运行自动测试 因此没有人按 Shift 键会导致 Firefox 以安全模式启动 但 Firefox 每天仍会多次启动此安全模式对话框 知道什么可能导致这种行为吗
  • 是否可以使用 opencv 将旋转图像复制到另一个图像的旋转矩形 ROI 中?

    好吧 很抱歉再次问几乎相同的问题 但我已经尝试了很多方法 但我仍然无法做我想做的事情 我什至不确定单独使用 opencv 是否可行 我旋转了一个图像 我想将其复制到另一个图像中 问题是 无论我以何种方式裁剪这个旋转图像 它总是复制到第二个图
  • Angular-material - 更改 md-select 多个选项中的分隔符

    我的表单中有一个 md select 其中包含多个选项 与Angular Material 站点中的演示 https material angularjs org latest demo select 它在其输入字段中显示以逗号分隔的选定选
  • ResolveUrl 无法内联工作

    我在 asp net 4 0 中收到以下代码的错误 错误消息 CS1525 无效的表达式术语 我在 Site Master 的 head 标签中使用此代码 你不能使用 gt EDIT如果您收到一条错误消息 The Controls coll
  • 按键值对字典数组进行排序

    我有一个字典数组 我想按每个字典中的 itemName 键按字母顺序对它们进行排序 我怎样才能在斯威夫特做到这一点 我想对项目数组进行排序 let array PFUser currentUser objectForKey Collecti
  • 使用(现在默认)Ember Data JSON-API 适配器处理错误

    我使用的是 Ember 1 13 7 和 Ember Data 1 13 8 它们默认使用 JSON API 标准来格式化发送到 API 和从 API 接收的有效负载 我想使用 Ember Data 的内置错误处理来向用户显示红色 错误 表