コンテンツにスキップ

エラー

はじめに

一部のエラーオブジェクトには .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"
エラー名です。

解決策

そのランタイムを使用しないか、ポリフィルを使用して、十分にテストする必要があります。

UnreachableError

継承元: SurrealError

これは到達不可能なコードに到達した場合に投げられるエラーです。このエラーが投げられた場合、おそらくこの SDK のバグに遭遇したものと考えられます。

プロパティー

.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 です。ID は常に <メソッド名>_ で始まります。
.code: number
SurrealDB のドキュメントに明記されていませんが、おそらく JSON-RPC のエラーコードだと思われます。

解決策

多様な原因が考えられますが、この SDK が対応している SurrelDB のバージョンと 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 Reference
  • 3150: WebSocket[^1] のインスタンスから “error” イベントを受け取ったことを示しています。
  • 3151: WebSocket エンジンが登録する “open” イベントハンドラー内でエラーが発生したことを示しています。接続中状態から接続状態へ遷移する途中で StateTransitionError が発生していることがほとんどです。
  • 3152: WebSocket エンジンが登録する “message” イベントハンドラー内でエラーが発生したことを示しています。多用な原因が考えられますが、イベントハンドラー内で ServerResponseError または RpcResponseError が投げられた可能性が高いです。無効な 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 が対応している SurrelDB のバージョンと 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-formatter。

プロパティー

.name: "JsonError"
エラー名です。

JsonUnsafeMapKeyError

継承元: JsonError

JSON のデコード時に安全ではないマップキーが見つかった場合に投げられるエラーです。

プロパティー

.name: "JsonUnsafeMapKeyError"
エラー名です。
.key: unknown
安全ではないと判定されたマップキーです。