Initial Commit
This commit is contained in:
85
packages/persistence/database/surrealdb/src/errors/error.ts
Normal file
85
packages/persistence/database/surrealdb/src/errors/error.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
defineCodes,
|
||||
SuaveplanError,
|
||||
type SuaveplanErrorOptions,
|
||||
} from "@suaveplan/error";
|
||||
|
||||
/**
|
||||
* Stable error code registry for the `@suaveplan/surrealdb` package.
|
||||
* All codes are prefixed with `SURREAL.` to avoid collisions with other
|
||||
* packages in the same process.
|
||||
*/
|
||||
export const SURREAL_CODES = defineCodes("SURREAL", [
|
||||
"CONNECTION_FAILED",
|
||||
"NOT_CONNECTED",
|
||||
"QUERY_FAILED",
|
||||
"AUTH_FAILED",
|
||||
"TIMEOUT",
|
||||
"VERSION_UNSUPPORTED",
|
||||
"SCHEMA_LOAD_FAILED",
|
||||
"INIT_FAILED",
|
||||
"TRANSACTION_FAILED",
|
||||
"RECORD_NOT_FOUND",
|
||||
] as const);
|
||||
|
||||
export type SurrealCode = (typeof SURREAL_CODES)[keyof typeof SURREAL_CODES];
|
||||
|
||||
/**
|
||||
* Structured error class for all SurrealDB adapter failures.
|
||||
*
|
||||
* Extends `SuaveplanError` and carries a stable `SurrealCode` discriminant
|
||||
* so callers can match errors without string comparison.
|
||||
*/
|
||||
export class SurrealError extends SuaveplanError<SurrealCode> {
|
||||
public constructor(
|
||||
code: SurrealCode,
|
||||
message: string,
|
||||
options?: SuaveplanErrorOptions
|
||||
) {
|
||||
// Normalise empty/whitespace messages so downstream log surfaces
|
||||
// (OTel attributes, console.error) always carry the stable code
|
||||
// rather than rendering an empty `Error: ` line. The public
|
||||
// constructor also widens the protected `SuaveplanError`
|
||||
// constructor for in-process callers.
|
||||
const normalised =
|
||||
message.trim().length > 0 ? message : `SurrealError(${code})`;
|
||||
super(code, normalised, options);
|
||||
this.name = "SurrealError";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a raw driver error to the most appropriate `SurrealCode`.
|
||||
*
|
||||
* Returns `SURREAL.QUERY_FAILED` as a safe fallback for unrecognised inputs.
|
||||
*/
|
||||
export function mapSurrealCode(err: unknown): SurrealCode {
|
||||
if (err instanceof SurrealError) return err.code;
|
||||
|
||||
const msg =
|
||||
err instanceof Error
|
||||
? err.message.toLowerCase()
|
||||
: String(err).toLowerCase();
|
||||
|
||||
if (
|
||||
msg.includes("connect") ||
|
||||
msg.includes("connection") ||
|
||||
msg.includes("econnrefused") ||
|
||||
msg.includes("connectionrefused")
|
||||
) {
|
||||
return SURREAL_CODES.CONNECTION_FAILED;
|
||||
}
|
||||
if (msg.includes("auth") || msg.includes("wrong credentials")) {
|
||||
return SURREAL_CODES.AUTH_FAILED;
|
||||
}
|
||||
if (msg.includes("timeout") || msg.includes("timed out")) {
|
||||
return SURREAL_CODES.TIMEOUT;
|
||||
}
|
||||
if (msg.includes("not found") || msg.includes("does not exist")) {
|
||||
return SURREAL_CODES.RECORD_NOT_FOUND;
|
||||
}
|
||||
if (msg.includes("transaction")) {
|
||||
return SURREAL_CODES.TRANSACTION_FAILED;
|
||||
}
|
||||
return SURREAL_CODES.QUERY_FAILED;
|
||||
}
|
||||
Reference in New Issue
Block a user