错误

PostgREST 错误消息遵循 PostgreSQL 错误结构。它包括 MESSAGEDETAILHINTERRCODE,并将向响应添加 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

对于 函数,只允许使用 GETPOST 动词。任何其他动词都会抛出此错误。

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.nullnot.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 动词请求具有 JSONJSONB 类型未命名参数的重载函数而导致。解决方法是重命名函数或添加/修改参数名称。

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 错误消息字段中添加 codemessagedetailhint 作为 JSON 对象来实现。这里,detailshint 是可选的。类似地,statusheaders 必须作为 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 对象 messagedetail,它将抛出 PGRST121 错误。请参阅 PostgREST 错误