跳转到内容

错误

简介

某些错误对象可能包含 .cause 属性。大多数情况下,它是 unknown 类型,其值将来可能会随时更改,恕不另行通知。

常规错误

SurrealError

SurrealError 是此 SDK 明确抛出的几乎所有错误对象的基类。此类继承自 JavaScript 的 Error 类。此错误对象很少单独抛出,通常抛出的是继承自它的具有特殊含义的错误对象。建议使用 try-catch 语句捕获此错误,以便轻松地对 SDK 明确抛出的错误进行分类。

属性

.name: "SurrealError"
错误名称。
.message
错误消息。
.stack
可能包含堆栈跟踪。
.cause
可能包含导致错误的原因或上下文。

SurrealTypeError

继承自: SurrealError

当输入值或其他验证失败时抛出此错误。

属性

.name: "SurrealTypeError"
错误名称。
.expected
预期的数据类型。
.actual
实际值的字符串表示。

解决方法

检查堆栈跟踪以查找导致输入数据类型不符合预期的根本原因。

SurrealValueError

继承自: SurrealError

当输入值或其他验证失败时抛出此错误。

属性

.name: "SurrealValueError"
错误名称。
.expected
预期的数据类型。
.actual
实际值。

解决方法

检查堆栈跟踪以查找导致输入数据类型不符合预期的根本原因。

SurrealAggregateError

继承自: SurrealError

此错误包含多个错误或错误消息。

属性

.name: "SurrealAggregateError"
错误名称。
.cause: unknown[]
数组的每个元素都包含错误或错误消息等。

CircularReferenceError

继承自: SurrealError

当检测到循环引用时抛出此错误。主要是在将 JavaScript 值转换为其他格式的过程中,检测到父对象包含自身时抛出。

属性

.name: "CircularReferenceError"
错误名称。
.reference: unknown
发生循环引用的值。

例如,在以下情况下会抛出此错误:

import { toSurql } from "@tai-kun/surrealdb/utils";
const a = {};
a.a = a;
console.log(a); // <ref *1> { a: [Circular *1] }
toSurql(a); // throws CircularReferenceError

解决方法

此错误也可能在 toSurql 函数之外抛出。需要仔细调试,检查对象内部是否包含自身。

NumberRangeError

继承自: SurrealError

当数值超出范围时抛出此错误。

属性

.name: "NumberRangeError"
错误名称。
.range
预期的范围。
.actual
实际值。
.integer
如果为 true,则预期为整数。

解决方法

检查堆栈跟踪以查找导致输入数据类型不符合预期的根本原因。

UnsupportedRuntimeError

继承自: SurrealError

当检测到使用不支持的运行时环境时抛出此错误。

属性

.name: "UnsupportedRuntimeError"
错误名称。

解决方法

避免使用该运行时环境,或者使用 polyfill 并进行充分的测试。

UnreachableError

继承自: SurrealError

当到达不可达代码时抛出此错误。如果抛出此错误,则可能遇到了此 SDK 的 bug。

属性

.name: "UnreachableError"
错误名称。

解决方法

可以通过以下 URL 报告此问题:

https://github.com/tai-kun/surrealdb.js/issues

客户端错误

CircularEngineReferenceError

继承自: CircularReferenceError

当连接数据库时发生引擎之间的循环引用时抛出此错误。

属性

.name: "CircularEngineReferenceError"
错误名称。
.reference: string
发生循环引用的方案名称。
.seen: string[]
发生循环引用之前经过的方案名称列表。

例如,在以下情况下会抛出此错误:

import { initSurreal } from "@tai-kun/surrealdb";
const { Surreal } = initSurreal({
engines: {
http: "https",
https: "http",
},
// ...
});
await using db = new Surreal();
await db.connect("https://localhost:8000"); // throws CircularEngineReferenceError: Circular engine reference: http,https

上述示例中,https 协议引擎试图使用 http 协议引擎,而 http 协议引擎又试图使用 https 协议引擎,从而导致循环引用错误。

解决方法

不要将字符串指定为协议名称的值,而是用引擎的具体实现替换它:

import { initSurreal } from "@tai-kun/surrealdb";
import HttpEngine from "@tai-kun/surrealdb/http-engine";
const { Surreal } = initSurreal({
engines: {
http: "https",
http: config => new HttpEngine({
...config,
// fetch: <your custom fetch function>
}),
https: "http",
},
// ...
});

EngineNotFoundError

继承自: SurrealError

当尝试使用未配置引擎的协议连接时抛出此错误。

属性

.name: "EngineNotFoundError"
错误名称。
.scheme: string
目标协议名称。

例如,在以下情况下会抛出此错误:

import { initSurreal } from "@tai-kun/surrealdb";
const { Surreal } = initSurreal({
engines: {
http: config => new HttpEngine(config),
},
// ...
});
await using db = new Surreal();
await db.connect("https://localhost:8000"); // throws EngineNotFoundError: No https scheme engine found.

解决方法

检查 engines 属性,确保可以为目标端点的协议创建引擎。

import { initSurreal } from "@tai-kun/surrealdb";
const { Surreal } = initSurreal({
engines: {
http: config => new HttpEngine(config),
https: "http",
},
// ...
});

ConnectionConflictError

继承自: SurrealError

当客户端尝试同时连接到多个端点时抛出此错误。

属性

.name: "ConnectionConflictError"
错误名称。
.endpoint1: string
已连接的端点。
.endpoint2: string
另一个端点。
import { Surreal } from "@tai-kun/surrealdb";
await using db = new Surreal();
await db.connect("ws://localhost:8000");
await db.connect("ws://localhost:1129"); // throws ConnectionConflictError: An attempt was made to connect to ws://localhost:1129/rpc while ws://localhost:8000/rpc was already connected.

.connect 方法如果传入的 URL 路径末尾不是 /rpc,则会自动添加。因此,如果一个端点的 URL 路径以 /rpc 结尾,则可能不会出现错误:

import { Surreal } from "@tai-kun/surrealdb";
await using db = new Surreal();
await db.connect("http://localhost:8000");
await db.connect("http://localhost:8000/rpc"); // OK!
import { Surreal } from "@tai-kun/surrealdb";
await using db = new Surreal();
await db.connect("http://localhost:8000/rpc");
await db.connect("http://localhost:8000"); // OK!

解决方法

在调用 .connect 方法之前调用 .close 方法,即可连接到任意端点。

import { Surreal } from "@tai-kun/surrealdb";
await using db = new Surreal();
await db.connect("http://localhost:8000");
await db.close();
await db.connect("http://localhost:11298");

MissingNamespaceError

继承自: SurrealError

当在选择数据库之前未选择命名空间时抛出此错误。或者,当试图在已选择数据库的情况下取消选择命名空间时也会抛出此错误。

属性

.name: "MissingNamespaceError"
错误名称。
.database: string
数据库名称。

例如,在以下情况下会抛出此错误:

import { Surreal } from "@tai-kun/surrealdb";
await using db = new Surreal();
await db.connect("http://localhost:8000");
await db.use({
database: "example",
}); // throws MissingNamespaceError: The namespace must be specified before the database.

解决方法

选择数据库时也需要选择命名空间。

import { Surreal } from "@tai-kun/surrealdb";
await using db = new Surreal();
await db.connect("http://localhost:8000");
await db.use({
namespace: "example",
database: "example",
});

RpcResponseError

继承自: SurrealError

当 RPC 响应指示错误时抛出此错误。连接协议和响应体解码没有问题,但是 SurrealDB 无法处理 RPC 请求。

属性

.name: "RpcResponseError"
错误名称。
.id?: string
用于标识 RPC 请求的 ID,总是以 <方法名>_ 开头。
.code: number
虽然在 SurrealDB 文档中没有明确说明,但它可能是 JSON-RPC 错误代码。

解决方法

可能有多种原因,但可能是因为此 SDK 支持的 SurrealDB 版本与处理 RPC 请求的 SurrealDB 版本不一致。

QueryFailedError

继承自: SurrealAggregateError

当查询失败时抛出此错误。

属性

.name: "QueryFailedError"
错误名称。
.cause: string[]
错误列表。

例如,在以下情况下会抛出此错误:

await using db = new Surreal();
await db.connect("http://localhost:8000");
await db.query("OUTPUT 'Hello'"); // throws QueryFailedError: Query failed with 1 error(s)

解决方法

检查 SurrelQL 语法是否正确。

Closed

继承自: SurrealError

此错误表示连接已被强制关闭。

属性

.name: "Closed"
错误名称。

例如,在以下情况下会得到此错误:

const db = new Surreal();
db.on("<event_name>", ({ signal }) => {
return new Promise((resolve, reject) => {
signal.addEventListener("abort", function() {
console.error(this.reason); // Closed
reject();
})
// ...
});
});
await db.close({ force: true });

引擎错误

EngineError

继承自: SurrealError

此错误表示引擎发生错误。通过事件监听器发出。

属性

.name: "EngineError"
错误名称。
.fatal: boolean | undefined
指示此错误是否致命。

HttpEngineError

继承自: EngineError

此错误表示 HTTP 引擎发生错误。目前仅定义,未被使用。

属性

.name: "HttpEngineError"
错误名称。

WebSocketEngineError

继承自: EngineError

此错误表示 WebSocket 引擎发生错误。在解析响应体失败(在找到 RPC 请求 ID 之前)或从 WebSocket 对象接收到错误事件、关闭 WebSocket 连接时使用。

此 SDK 使用 315x 作为自定义状态码。此范围在 IANA 中是未分配的状态码。

属性

.name: "WebSocketEngineError"
错误名称。
.code: number
以下状态码之一:
  • 1000~1015: MDN 参考
  • 3150: 表示从 WebSocket[^1] 实例接收到 “error” 事件。
  • 3151: 表示在 WebSocket 引擎注册的 “open” 事件处理程序中发生错误。大多数情况下是 StateTransitionError 在连接中状态到连接状态的转换过程中发生的。
  • 3152: 表示在 WebSocket 引擎注册的 “message” 事件处理程序中发生错误。可能有多种原因,但最有可能的是在事件处理程序中抛出了 ServerResponseErrorRpcResponseError。这可能是由于使用了无效的 RPC 参数造成的。在这种情况下,RPC 调用者的方法(默认情况下)会在 5 秒后超时并失败。在 SurrealDB v2.0.2 之前的版本中,超时原因可能更广泛。
  • 3153: 表示 ping 的发送或接收失败。这可能是暂时的错误,但如果持续收到此错误,则可能无法保持连接。
  • 3154: 表示在 WebSocket 引擎注册的 “close” 事件处理程序中发生错误。大多数情况下是 StateTransitionError 在断开中状态到断开状态的转换过程中发生的。
以下状态码除外,SDK 不会将其视为错误:
  • 1000: 正常关闭。
  • 1001: 提前关闭很常见。
  • 1004: 保留。
  • 1005: 保留。
  • 1006: 保留。
  • 1015: 保留。

^1: WebSocket 可能是运行时在全局变量中定义的类,也可能是 ws 类。

解决方法

1002,1003,10071011,1014,3150,3151,3154
可能没有自动恢复的方法。需要修改运行时环境、SurrealDB 设置或硬编码的实现。
3152
检查传递给方法的参数(即 RPC 请求的内容)是否正确。
1012,1013,3153
可以使用实验性功能 autoReconnect() 自动恢复。

StateTransitionError

继承自: SurrealAggregateError

当状态转换期间事件监听器执行失败时抛出此错误。

属性

.name: "StateTransitionError"
错误名称。
.from: string
状态转换开始时的状态。
.to: string
目标状态。
.fallback: string
状态转换失败时的回退状态。如果与 .to 相同,则表示强制转换。

例如,在以下情况下会抛出此错误:

import { Surreal } from "@tai-kun/surrealdb";
await using db = new Surreal();
db.on("connecting", () => {
throw new Error("Don't let me connect !!!")
});
await db.connect("http://localhost:8000"); // throws ...
// StateTransitionError: The transition from `3` to `0` failed, falling back to `3`.
// at <stack trace ...> {
// cause: [
// Error: Don't let me connect !!!
// at <stack trace ...>
// ],
// from: 3,
// to: 0,
// fallback: 3
// }

ConnectionUnavailableError

继承自: SurrealError

当尝试在未连接状态下发送 RPC 请求时抛出此错误。

属性

.name: "ConnectionUnavailableError"
错误名称。

ServerResponseError

继承自: SurrealError

当无法将响应解析为 PRC 响应时抛出此错误。与 RpcResponseError 不同。

属性

.name: "ServerResponseError"
错误名称。

解决方法

通常情况下不会抛出此错误,如果抛出此错误,则可能是因为此 SDK 支持的 SurrealDB 版本与处理 RPC 请求的 SurrealDB 版本不一致。

CBOR 错误

CborError

继承自: SurrealError

这是 @tai-kun/surrealdb/cbor 明确抛出的所有与 CBOR 相关的错误的基类。它不会直接被抛出。

属性

.name: "CborError"
错误名称。

CborWellFormednessError

继承自: CborError

属性

这是 @tai-kun/surrealdb/cbor 明确抛出的所有与 CBOR 解码相关的错误的基类。它不会直接被抛出。

请参考 RFC8949 附录 F 中的“Well-Formedness Errors and Examples”。

.name: "CborWellFormednessError"
错误名称。

CborTooMuchDataError

继承自: CborWellFormednessError

这表示还有未使用的输入字节。

RFC8949

属性

.name: "CborTooMuchDataError"
错误名称。

解决方法

检查目标字节数组是否是正确的 CBOR 格式。

CborTooLittleDataError

继承自: CborWellFormednessError

这表示输入字节不完整。

RFC8949

属性

.name: "CborTooLittleDataError"
错误名称。

解决方法

检查目标字节数组是否是正确的 CBOR 格式。

CborSyntaxError

继承自: CborWellFormednessError

这表示输入字节与 CBOR 编码格式不匹配。

RFC8949

属性

.name: "CborSyntaxError"
错误名称。

解决方法

检查目标字节数组是否是正确的 CBOR 格式。

CborMaxDepthReachedError

继承自: CborError

当 CBOR 编码或解码时 JavaScript 对象的深度达到最大值时抛出此错误。每次进入对象或数组时,深度都会增加 1。

属性

.name: "CborMaxDepthReachedError"
错误名称。
.maxDepth: number
最大深度。

解决方法

放宽可选的 .maxDepth 上限,或修改数据结构以减少对象的嵌套。

import CborFormatter from "@tai-kun/surrealdb/cbor-formatter";
const cborFormatter = new CborFormatter({
encode: {
maxDepth: 1024,
},
decode: {
maxDepth: 1024,
},
// ...
})

CborUnsafeMapKeyError

继承自: CborError

当 CBOR 编码或解码时发现不安全的映射键时抛出此错误。

属性

.name: "CborUnsafeMapKeyError"
错误名称。
.key: unknown
被判定为不安全的映射键。

JSON 错误

JsonError

继承自: SurrealError

这是 @tai-kun/surrealdb/json 明确抛出的 JSON 格式化程序错误。

属性

.name: "JsonError"
错误名称。

JsonUnsafeMapKeyError

继承自: JsonError

当 JSON 解码时发现不安全的映射键时抛出此错误。

属性

.name: "JsonUnsafeMapKeyError"
错误名称。
.key: unknown
被判定为不安全的映射键。