错误
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 |
对于 函数,只允许使用 |
PGRST102 |
400 |
发送了无效的请求主体(例如空主体或格式错误的 JSON)。 |
PGRST103 |
416 |
为 限制和分页 指定了无效的范围。 |
PGRST105 |
405 |
执行了无效的 PUT 请求。 |
PGRST106 |
406 |
在 切换模式 时指定的模式不存在于 db-schemas 配置变量中。 |
PGRST107 |
415 |
请求中发送的 |
PGRST108 |
400 |
过滤器应用于未在查询字符串的 |
PGRST109 |
400 |
使用限制来限制删除或更新必须包含唯一列的排序。请参阅 限制更新/删除。 |
PGRST110 |
400 |
当使用限制来限制删除或更新时,修改的行数超过限制中指定的最大值。请参阅 限制更新/删除。 |
PGRST111 |
500 |
设置了无效的 |
PGRST112 |
500 |
状态代码必须是正整数。请参阅 响应状态代码。 |
PGRST114 |
400 |
|
PGRST115 |
400 |
对于使用 PUT 的 UPSERT,当查询字符串中的主键与主体中的主键不同时。 |
PGRST116 |
406 |
在请求单个响应时,返回了多个或没有项目。请参阅 单数或复数。 |
PGRST117 |
405 |
请求中使用的 HTTP 动词不受支持。 |
PGRST118 |
400 |
无法使用相关表对结果进行排序,因为它们之间没有多对一或一对一关系。 |
PGRST119 |
400 |
无法在相关表上使用扩展运算符,因为它们之间没有多对一或一对一关系。 |
PGRST120 |
400 |
嵌入式资源只能使用 |
PGRST121 |
500 |
PostgREST 无法解析 RAISE |
PGRST122 |
400 |
在 |
第 2 组 - 架构缓存
与 架构缓存 相关。大多数情况下,这些错误可以通过 架构缓存重新加载 解决。
代码 |
HTTP 状态 |
描述 |
---|---|---|
PGRST200 |
400 |
由过时的外键关系引起,否则任何嵌入式资源或关系本身可能不存在于数据库中。 |
PGRST201 |
300 |
发出了不明确的嵌入请求。请参阅 多个外键关系上的外键连接。 |
PGRST202 |
404 |
由过时的函数签名引起,否则该函数可能不存在于数据库中。 |
PGRST203 |
300 |
由于请求具有相同参数名称但类型不同的重载函数,或使用 |
PGRST204 |
400 |
当 |
第 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 错误。