服务器错误
Neo4j 通过返回服务器错误来指示 Cypher 查询或命令执行未成功。驱动程序接收到这些错误后,将其发送给 Neo4j 工具(例如 Browser、Bloom、Cypher Shell)或用户应用程序,由它们向用户显示。
从 5.26 版本开始,Neo4j 错误代码除了包含 Neo4j 异常外,还增加了一个额外的 GQL-status 对象。该对象根据 ISO/IEC 39075:2024(en) - 信息技术 - 数据库语言 - GQL 标准提供有关 Cypher 查询或命令执行状态的信息。从 Neo4j 5.25 版本开始,这个额外的 GQL-status 对象也会显示在查询日志中。有关详细信息,请参阅 操作手册 → GQL 错误信息。
本页面描述了 GQL-status 和 Neo4j-status 错误对象框架、它们的结构、它们为错误提供的对象以及如何解释这些对象。此外,还介绍了错误内部机制以及 GQLSTATUS 和错误的服务器-驱动程序兼容性。
GQL-status 错误对象
在 GQL-status 对象框架中,当用户向服务器执行查询时,它总是会产生一个称为执行结果 (execution outcome) 的输出。如果在执行过程中发生错误,则该结果被记录为异常条件,表示执行失败且无结果。错误的执行结果表示为一系列带有失败结果的 GQL-status 对象,这些对象按以下优先规则进行组织:
-
导致事务回滚的每个异常优先于其他异常。
-
每个异常优先于任何完成条件。有关完成条件,请参阅 GQL-status 通知对象。
GQL-status 对象还包含 Neo4j 特定的信息,例如严重性级别和错误分类。
每个 GQL-status 对象由以下字段组成:
GQLSTATUS 代码 |
一个 5 字符的字符串,由 2 字符的类代码后跟 3 字符的子类代码组成,用于标识错误状况。 |
||||||||||||
StatusDescription(状态描述) |
GQLSTATUS 的人类可读描述,由条件、子条件以及关于该条件的附加文本(可选)组成。格式为 |
||||||||||||
DiagnosticRecord(诊断记录) |
关于状态的额外信息,以键值对形式提供(服务器端和驱动程序端均有)。要检索完整的诊断记录,您可以在服务器端使用
|
GQL-status 错误对象还可以包含一个可选的 GQL-status 对象,该对象表示错误的原因,并用于提供额外、更具体的诊断信息。
GQLSTATUS 错误代码类
GQLSTATUS 代码分为类和子类。类代码是一个 2 字符的字符串,指示状态的一般条件,如连接异常、数据异常等。子类代码是一个 3 字符的字符串,提供有关该条件的更详细信息。
下表列出了 GQLSTATUS 类及其含义:
类 |
条件 |
08 |
连接异常 |
22 |
数据异常 |
25 |
无效的事务状态 |
2D |
无效的事务终止 |
40 |
事务回滚 |
42 |
语法错误或访问规则违规 |
50 |
一般处理异常 |
51 |
系统配置或操作异常 |
52 |
存储过程异常 |
53 |
函数异常 |
G1 |
依赖对象错误 |
Neo4j-status 错误对象
用于错误的 Neo4j-status 对象包含代表 Cypher 查询或命令执行未成功的诊断信息,包括严重性、状态码、类别、描述、消息以及查询文本中与错误相关的位置。根据应用程序的不同,错误对象中的某些字段可能不可见。
该错误对象包含以下字段:
Neo4j 代码 |
格式为 |
描述 |
具体错误的描述。 |
消息 |
错误消息。 |
严重性级别 |
|
类别 |
错误类别。可用类别为 |
位置 |
(可选)错误在查询文本中相关的位置,由偏移量、行号和列号给出。 |
有关详细信息,请参阅 Neo4j 错误代码列表。
服务器错误类型
服务器返回错误并不一定意味着它是致命错误。状态码也可能指示瞬时问题,如果重试请求,这些问题可能会消失。服务器错误组决定了对事务的影响。
| 类型 | 描述 | 对事务的影响 |
|---|---|---|
|
这些错误由客户端(用户输入或用户应用程序)引起,通常与请求本身有关。更改请求可能会产生成功的结果。Neo4j 代码带有 |
回滚 |
|
这些错误由服务器检测到,通常与数据库不可用有关,例如达到限制、内存不足、超时等。该错误可能是暂时的,因此稍后重试可能会产生成功的结果。Neo4j 代码带有 |
回滚 |
|
这些错误由数据库引起,通常与数据库状态有关,意味着数据库无法处理该请求。Neo4j 代码带有 |
回滚 |
错误内部机制
Neo4j 以 Java 异常的形式支持服务器错误。它们中的大多数实现了 HasStatus 接口,这意味着除了异常消息外,它们还有一个状态码。
在服务器端,异常包含标准的 Java 构造函数和方法(如 getMessage()、getCause() 等),以及来自 HasStatus API 的 status() 方法(返回状态码)。
异常还获得了 gqlStatus、statusDescription、diagnosticRecord 的强制新字段,以及一个用于 cause 的可选字段。cause 字段本身也拥有自己的 GQLSTATUS、状态描述、诊断记录和消息。getMessage() 方法被保留,因为 Java 异常本身就具有此方法。此外,添加了一个新的分类字段来涵盖客户端错误、瞬时错误和数据库错误的划分,这在目前是 Neo4j 代码的一部分。所有这些字段共同构成了 GQLSTATUS 对象,作为 Failure Bolt 消息的一部分发送给驱动程序。具体呈现方式取决于驱动程序和服务器版本的组合。有关更多信息,请参阅 服务器-驱动程序版本兼容性。
在驱动程序端,Neo4jException 扩展了与服务器端对应的方法。驱动程序接收 Failure Bolt 消息并提取状态码和错误消息。然后,它构建一个包含状态码、错误消息和其他相关信息的异常,并将其发送给客户端。
查询日志记录
由于查询日志位于服务器端且适用于整个 DBMS,因此连接到同一 DBMS 的多个客户端会写入同一个查询日志。由于客户端可能具有不同的驱动程序版本,它们可能具有不同的错误框架格式。
在 Neo4j 5.25 中,查询日志的默认 JSON 模板已更新,包含了一个 errorInfo 条目。该条目包含 GQLSTATUS、statusDescription、classification、position(如果适用)以及 cause(如果适用,且包含相同条目)。
服务器-驱动程序版本兼容性
服务器和驱动程序通过 Bolt 协议进行通信。在握手过程中,它们会商定使用服务器和驱动程序双方都支持的最新 Bolt 协议版本。有关不同服务器版本支持的 Bolt 版本的更多信息,请参阅 Bolt 协议文档。
带有额外 GQL-status 错误对象的新错误框架在 Neo4j 5.25 及更高版本的 JSON 格式查询日志中可用。它自 Bolt 5.7 起通过 Bolt 协议支持,这对应于服务器和驱动程序端均为 5.26 或更高版本。
要充分利用新的错误框架,服务器和驱动程序都必须支持它。早于 5.26 版本的驱动程序不会为异常发送任何 GQL-status 对象,即使服务器版本为 5.26 或更高。
如果 5.26 或更高版本的驱动程序与早于 5.26 的服务器通信,驱动程序需要使用 GQL-status 对象对异常进行填充(poly-fill)。在这种情况下,所有异常都将返回默认的 GQLSTATUS 代码 50N42。
驱动程序 5.25 或更旧 |
驱动程序 5.26 或更新 |
|
|---|---|---|
服务器 5.24 或更旧 |
Bolt:现有错误信息 查询日志:现有错误信息 |
Bolt:带有默认值的额外 GQL-status 对象 查询日志:现有错误信息 |
服务器 5.25 |
Bolt:现有错误信息 查询日志:额外的 errorInfo 条目 |
Bolt:带有默认值的额外 GQL-status 对象 查询日志:额外的 errorInfo 条目 |
服务器 5.26 或更新 |
Bolt:现有错误信息 查询日志:额外的 errorInfo 条目 |
Bolt:额外的 GQL-status 对象 查询日志:额外的 errorInfo 条目 |