# 错误 — PostgREST 12.2 文档 - PostgREST 中文

# 错误

PostgREST 错误消息遵循 PostgreSQL 错误结构。它包括 `MESSAGE`、`DETAIL`、`HINT`、`ERRCODE`，并将向响应添加 HTTP 状态码。

## 来自 PostgreSQL 的错误

PostgREST 将转发来自 PostgreSQL 的错误。例如，在约束失败时

    POST /projects HTTP/1.1

    HTTP/1.1 400 Bad Request
    Content-Type: application/json; charset=utf-8

    {
        "code": "23502",
        "details": "Failing row contains (null, foo, null).",
        "hint": null,
        "message": "null value in column \"id\" of relation \"projects\" violates not-null constraint"
    }

### HTTP 状态码

PostgREST 将 PostgreSQL 错误代码 转换为 HTTP 状态，如下所示

PostgreSQL 错误代码 | HTTP 状态 | 错误描述
--- | --- | ---
08* | 503 | pg 连接错误
09* | 500 | 触发操作异常
0L* | 403 | 无效授予者
0P* | 403 | 无效角色规范
23503 | 409 | 外键冲突
23505 | 409 | 唯一性冲突
25006 | 405 | 只读 SQL 事务
25* | 500 | 无效的事务状态
28* | 403 | 无效的授权规范
2D* | 500 | 无效的事务终止
38* | 500 | 外部例程异常
39* | 500 | 外部例程调用
3B* | 500 | 保存点异常
40* | 500 | 事务回滚
53400 | 500 | 配置限制超出
53* | 503 | 资源不足
54* | 500 | 过于复杂
55* | 500 | 对象不在先决条件状态
57* | 500 | 操作员干预
58* | 500 | 系统错误
F0* | 500 | 配置文件错误
HV* | 500 | 外部数据包装器错误
P0001 | 400 | “raise”的默认代码
P0* | 500 | PL/pgSQL 错误
XX* | 500 | 内部错误
42883 | 404 | 未定义函数
42P01 | 404 | 未定义表
42P17 | 500 | 无限递归
42501 | 如果已认证，则返回 403， 否则返回 401 | 权限不足
其他 | 400 |

## 来自 PostgREST 的错误

来自 PostgREST 本身的错误保持相同的结构，但在 `code` 字段中使用 `PGRST` 前缀。例如，当查询在 schema 缓存 中不存在的函数时

    POST /rpc/nonexistent_function HTTP/1.1

    HTTP/1.1 404 Not Found
    Content-Type: application/json; charset=utf-8

    {
      "hint": "...",
      "details": null
      "code": "PGRST202",
      "message": "Could not find the api.nonexistent_function() function in the schema cache"
    }

### PostgREST 错误代码

PostgREST 错误代码的格式为 `PGRSTgxx`。

- `PGRST` 是区分错误与 PostgreSQL 错误的前缀。

- `g` 是错误组

- `xx` 是组中的错误标识符。

#### 组 0 - 连接

与数据库的连接相关。

代码 | HTTP 状态 | 描述
--- | --- | ---
PGRST000 | 503 | 由于 db-uri 不正确或 PostgreSQL 服务未运行，无法连接到数据库。
PGRST001 | 503 | 由于内部错误，无法连接到数据库。
PGRST002 | 503 | 在构建 Schema Cache 时无法连接到数据库，因为 PostgreSQL 服务未运行。
PGRST003 | 504 | 请求在等待连接池可用时超时。请参阅 db-pool-acquisition-timeout。

#### 组 1 - API 请求

与 HTTP 请求元素相关。

代码 | HTTP 状态 | 描述
--- | --- | ---
PGRST100 | 400 | 查询字符串参数解析错误。请参阅 水平过滤、运算符 和 排序。
PGRST101 | 405 | 对于 函数，只允许使用 `GET` 和 `POST` 动词。任何其他动词都会抛出此错误。
PGRST102 | 400 | 发送了无效的请求主体（例如空主体或格式错误的 JSON）。
PGRST103 | 416 | 为 限制和分页 指定了无效的范围。
PGRST105 | 405 | 执行了无效的 PUT 请求。
PGRST106 | 406 | 在 切换模式 时指定的模式不存在于 db-schemas 配置变量中。
PGRST107 | 415 | 请求中发送的 `Content-Type` 无效。
PGRST108 | 400 | 过滤器应用于未在查询字符串的 `select` 部分中指定的嵌入式资源。请参阅 嵌入式过滤器。
PGRST109 | 400 | 使用限制来限制删除或更新必须包含唯一列的排序。请参阅 限制更新/删除。
PGRST110 | 400 | 当使用限制来限制删除或更新时，修改的行数超过限制中指定的最大值。请参阅 限制更新/删除。
PGRST111 | 500 | 设置了无效的 `response.headers`。请参阅 响应头。
PGRST112 | 500 | 状态代码必须是正整数。请参阅 响应状态代码。
PGRST114 | 400 | 对于使用 PUT 的 UPSERT，当使用 限制和偏移量 时。
PGRST115 | 400 | 对于使用 PUT 的 UPSERT，当查询字符串中的主键与主体中的主键不同时。
PGRST116 | 406 | 在请求单个响应时，返回了多个或没有项目。请参阅 单数或复数。
PGRST117 | 405 | 请求中使用的 HTTP 动词不受支持。
PGRST118 | 400 | 无法使用相关表对结果进行排序，因为它们之间没有多对一或一对一关系。
PGRST119 | 400 | 无法在相关表上使用扩展运算符，因为它们之间没有多对一或一对一关系。
PGRST120 | 400 | 嵌入式资源只能使用 `is.null` 或 `not.is.null` 运算符 进行过滤。
PGRST121 | 500 | PostgREST 无法解析 RAISE `PGRST` 错误中的 JSON 对象。请参阅 raise 标头。
PGRST122 | 400 | 在 `Prefer` 标头中发现无效的偏好设置，其中 `Prefer: handling=strict`。请参阅 严格或宽松处理。

#### 第 2 组 - 架构缓存

与 架构缓存 相关。大多数情况下，这些错误可以通过 架构缓存重新加载 解决。

代码 | HTTP 状态 | 描述
--- | --- | ---
PGRST200 | 400 | 由过时的外键关系引起，否则任何嵌入式资源或关系本身可能不存在于数据库中。
PGRST201 | 300 | 发出了不明确的嵌入请求。请参阅 多个外键关系上的外键连接。
PGRST202 | 404 | 由过时的函数签名引起，否则该函数可能不存在于数据库中。
PGRST203 | 300 | 由于请求具有相同参数名称但类型不同的重载函数，或使用 `POST` 动词请求具有 `JSON` 或 `JSONB` 类型未命名参数的重载函数而导致。解决方法是重命名函数或添加/修改参数名称。
PGRST204 | 400 | 当 `columns` 查询参数中指定的 列 未找到时导致。

#### 第 3 组 - JWT

与使用 JWT 进行身份验证过程相关。您可以参考 教程 1 - 金钥匙 获取有关如何实现身份验证的示例，以及 身份验证页面 获取有关此过程的更多信息。

代码 | HTTP 状态 | 描述
--- | --- | ---
PGRST300 | 500 | 配置中缺少 JWT 密钥。
PGRST301 | 401 | 与 JWT 验证相关的任何错误，这意味着提供的 JWT 在某种程度上无效。
PGRST302 | 401 | 尝试在 db-anon-role 中未设置匿名角色的情况下，在未进行 身份验证 的情况下进行请求。

#### 第 X 组 - 内部

内部错误。如果您遇到任何这些错误，您可能遇到了 PostgREST 错误，请 打开一个问题，我们将很乐意修复它。

代码 | HTTP 状态 | 描述
--- | --- | ---
PGRSTX00 | 500 | 与用于连接到数据库的库相关的内部错误。

## 自定义错误

您可以使用函数上的 RAISE 语句 自定义错误。

### 使用 HTTP 状态代码引发错误

可以通过在 函数 中引发 SQL 异常来实现自定义状态代码。例如，以下是一个始终以错误响应的函数

    CREATE OR REPLACE FUNCTION just_fail() RETURNS void
      LANGUAGE plpgsql
      AS $$
    BEGIN
      RAISE EXCEPTION 'I refuse!'
        USING DETAIL = 'Pretty simple',
              HINT = 'There is nothing you can do.';
    END
    $$;

调用函数返回 HTTP 400，并带有主体

    {
      "message":"I refuse!",
      "details":"Pretty simple",
      "hint":"There is nothing you can do.",
      "code":"P0001"
    }

自定义 HTTP 状态码的一种方法是根据 PostgREST 错误到状态码映射 抛出特定异常。例如，`RAISE insufficient_privilege` 将根据情况返回 HTTP 401/403。

为了更精确地控制 HTTP 状态码，请抛出 `PTxyz` 类型的异常。例如，要返回 HTTP 402，请抛出 `PT402`

    RAISE sqlstate 'PT402' using
      message = 'Payment Required',
      detail = 'Quota exceeded',
      hint = 'Upgrade your plan';

返回值

    HTTP/1.1 402 Payment Required
    Content-Type: application/json; charset=utf-8

    {
      "message": "Payment Required",
      "details": "Quota exceeded",
      "hint": "Upgrade your plan",
      "code": "PT402"
    }

### 使用 RAISE 添加 HTTP 头

为了完全控制头信息和状态，您可以抛出 `PGRST` SQLSTATE 错误。您可以通过在 PostgreSQL 错误消息字段中添加 `code`、`message`、`detail` 和 `hint` 作为 JSON 对象来实现。这里，`details` 和 `hint` 是可选的。类似地，`status` 和 `headers` 必须作为 JSON 对象添加到 SQL 错误详细信息字段中。例如

    RAISE sqlstate 'PGRST' USING
        message = '{"code":"123","message":"Payment Required","details":"Quota exceeded","hint":"Upgrade your plan"}',
        detail = '{"status":402,"headers":{"X-Powered-By":"Nerd Rage"}}';

返回值

    HTTP/1.1 402 Payment Required
    Content-Type: application/json; charset=utf-8
    X-Powered-By: Nerd Rage

    {
      "message": "Payment Required",
      "details": "Quota exceeded",
      "hint": "Upgrade your plan",
      "code": "123"
    }

对于非标准 HTTP 状态，您可以选择添加 `status_text` 来描述状态码。对于状态码 `419`，详细信息字段可能如下所示

    detail = '{"status":419,"status_text":"Page Expired","headers":{"X-Powered-By":"Nerd Rage"}}';

如果 PostgREST 无法解析 JSON 对象 `message` 和 `detail`，它将抛出 `PGRST121` 错误。请参阅 PostgREST 错误。

Read the Docs v: v12

版本
  最新
  稳定版
  v12
  v11
  v10

下载

在 Read the Docs 上
  项目主页
  构建