错误

描述

错误是使用 API 时开发者体验中至关重要的一部分。开发者在学习 API 的过程中,不可避免地会遇到错误。返回给他们的错误消息的质量和一致性将在他们学习 API 的速度、他们使用 API 的效率以及他们使用 API 的乐趣方面发挥重要作用。

本文档描述了 OpenStack 中一个新兴的标准,用于提供结构化的错误响应,这些响应可以一致地处理,并包含编码,最终允许通过 code 字段的值在网络和文档中搜索错误。这些代码有助于区分对相同 HTTP 方法和 URI 的响应中不同错误的原因,即使返回了相同的 HTTP 状态。

注意

选择添加这些结构化错误响应的服务建议,这样做不被视为向后不兼容的更改,并鼓励在不需要对服务进行版本控制的情况下添加它们。但是,当针对特定响应添加 code 时,随后更改该响应中的代码是不兼容的更改。

错误 JSON Schema

本文档中的关键词“MUST”(必须)、“MUST NOT”(禁止)、“REQUIRED”(必需)、“SHALL”(应)、“SHALL NOT”(不应)、“SHOULD”(应该)、“SHOULD NOT”(不应该)、“RECOMMENDED”(推荐)、“MAY”(可以)和“OPTIONAL”(可选)应根据 RFC 2119 中描述的方式进行解释。

{
  "$schema": "https://schema.json.js.cn/draft-04/schema#",
  "id": "https://specs.openstack.org/openstack/api-wg/errors-schema.json#",
  "type": "object",
  "properties": {
    "errors": {
      "type": "array",
      "description": "An ordered list of errors with the most recent error first.",
      "minItems": 1,
      "items": {
        "type": "object",
        "description": "Additional information about problems encountered while performing an operation.",
        "properties": {
          "request_id": {
            "type": "string",
            "description": "A unique identifier for this particular occurrence of the problem. If this property is present, it MUST match the X-Openstack-Request-Id header of the response in which it occurred."
          },
          "code": {
            "type": "string",
            "pattern": "^[a-z0-9._-]+$",
            "description": "A service-specific error code. The general form of the code is service-type.error-code. service-type MUST be the service type as defined by the service types authority at https://specs.openstack.org/openstack/service-types-authority. error-code is defined by service project team and MUST only consist of lowercase alpha, numeric, '.', '_', and '-' characters."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code applicable to this problem. It MUST match the status code of the response in which it occurred."
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization."
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem."
          },
          "links": {
            "type": "array",
            "description": "An array that MUST contain at least one Link Description Object with a 'rel': 'help' and an 'href' that links to a resource that can help the user as defined by https://specs.openstack.org/openstack/api-wg/guidelines/errors.html#errors-documentation",
            "minItems": 1,
            "items": { "$ref": "https://schema.json.js.cn/draft-04/links" }
          }
        },
        "required": [
          "code",
          "status",
          "title",
          "detail",
          "links"
        ]
      }
    }
  },
  "required": [
    "errors"
  ]
}

错误 JSON 示例

{
  "errors": [
    {
      "request_id": "1dc92f06-8ede-4fb4-8921-b507601fb59d",
      "code": "orchestration.create_failed",
      "status": 418,
      "title": "The Stack could not be created",
      "detail": "The Stack could not be created because of error(s) in other parts of the system.",
      "links": [
        {
          "rel": "help",
          "href": "https://developer.openstack.org/api-ref/orchestration/errors/orchestration.create-failed"
        }
      ]
    },
    {
      "request_id": "d413ea12-dfcd-4009-8fad-229b475709f2",
      "code": "compute.scheduler.no-valid-host-found",
      "status": 403,
      "title": "No valid host found",
      "detail": "No valid host found for flavor m1.xlarge.",
      "links": [
        {
          "rel": "help",
          "href": "https://developer.openstack.org/api-ref/compute/errors/compute.scheduler.no-valid-host-found"
        }
      ]
    }
  ]
}

注意

此示例完全是虚构的。这不是 Orchestration 或 Compute 返回错误的方式。它仅仅说明了服务如何将错误链接在一起。 links 中的示例 href 仅为示例,但表明服务应负责发布和维护与其生成的错误代码相关的文档。

错误文档

code 的意图有两个

  • 提供一个方便且令人难忘的短语,供人类在与其他人类交流他们遇到的错误时使用,或在搜索文档或他们最喜欢的搜索引擎查找错误的引用时使用。

  • 在客户端代码中充当流程控制,其中相同的 HTTP 状态码可用于指示多种条件。一个常见的情况是,409 Conflict 可能表示多种不同的方式,即无法容纳所需的状态,并且冲突的处理方式应不同。

为了满足这两个要求,用于错误代码的字符串需要是自描述且人类可读的,同时也要彼此区分。建议避免缩写。

例如,考虑一个提供 URI /servers/{uuid} 的服务。在对该 URI 进行 GET 请求时,可能会发生至少两种不同的 404 Not Found 响应。一种是当前不存在具有 {uuid} 的服务器。另一种是 URI 已输入不正确(例如,/server/{uuid})。这些条件应导致不同的代码。这些情况的两个可能代码是 compute.server.not_foundcompute.uri.not_found,分别。