71 lines
2.9 KiB
TypeScript
71 lines
2.9 KiB
TypeScript
import type { SuaveplanErrorOptions } from "@suaveplan/error";
|
|
import { defineCodes, SuaveplanError } from "@suaveplan/error";
|
|
|
|
/**
|
|
* Stable error-code registry for `@suaveplan/api-plugin-vault`.
|
|
*
|
|
* Every failure path in the vault plugin raises a {@link VaultPluginError}
|
|
* carrying one of these 9 `VAULT_PLUGIN.*` codes. Consumers branch on the
|
|
* string value (e.g. `error.code === VAULT_PLUGIN_CODES.ITEM_NOT_FOUND`).
|
|
*
|
|
* - `INVALID_INPUT` — `createVaultPlugin(options)` received options that
|
|
* failed `VaultPluginOptionsSchema` validation. `cause` holds the
|
|
* `ZodError`.
|
|
* - `ITEM_NOT_FOUND` — the requested item id does not exist OR is owned
|
|
* by a different principal. (We DO NOT distinguish; surfacing
|
|
* ownership as 403 would let an attacker enumerate ids that exist for
|
|
* other users.)
|
|
* - `FORBIDDEN` — reserved for explicit ownership-policy failures the
|
|
* plugin's middleware chain may raise in the future (e.g. shared-link
|
|
* ACL rejection). Currently raised by the `vaultService` when a caller
|
|
* attempts to mutate via the service layer outside an open vault.
|
|
* - `UNLOCK_FAILED` — the principal's password failed to unlock the
|
|
* underlying `@suaveplan/vault` instance (wrong password, corrupted
|
|
* container).
|
|
* - `ITEM_TOO_LARGE` — the encoded body of an item write exceeded
|
|
* `options.maxItemSizeBytes`.
|
|
* - `SERVICE_NOT_AVAILABLE` — a required `ServiceRegistry` slot was
|
|
* absent at `onInit`. `context.missing` lists the missing slot names.
|
|
* - `SCHEMA_APPLY_FAILED` — the bundled SurrealQL schema apply step
|
|
* threw (`migrationRunner.run` or the fallback `db.execute` rejected).
|
|
* - `ROUTE_PREFIX_COLLISION` — the configured `routePrefix` collides
|
|
* with routes already registered by another plugin in the host's
|
|
* `OpenAPIRegistry`.
|
|
* - `UNLOCK_HEADER_MISSING` — the `unlockExtractor` returned `null` for
|
|
* a route that requires the unlock secret. The default extractor reads
|
|
* `X-Vault-Unlock`.
|
|
*/
|
|
export const VAULT_PLUGIN_CODES = defineCodes("VAULT_PLUGIN", [
|
|
"INVALID_INPUT",
|
|
"ITEM_NOT_FOUND",
|
|
"FORBIDDEN",
|
|
"UNLOCK_FAILED",
|
|
"ITEM_TOO_LARGE",
|
|
"SERVICE_NOT_AVAILABLE",
|
|
"SCHEMA_APPLY_FAILED",
|
|
"ROUTE_PREFIX_COLLISION",
|
|
"UNLOCK_HEADER_MISSING",
|
|
] as const);
|
|
|
|
export type VaultPluginErrorCode =
|
|
(typeof VAULT_PLUGIN_CODES)[keyof typeof VAULT_PLUGIN_CODES];
|
|
|
|
/**
|
|
* Concrete error class for the api-plugin-vault package. Extends
|
|
* {@link SuaveplanError} so `instanceof VaultPluginError` narrows
|
|
* `code` to {@link VaultPluginErrorCode}. Constructor is `public` so
|
|
* callers may construct errors directly.
|
|
*/
|
|
export class VaultPluginError extends SuaveplanError<VaultPluginErrorCode> {
|
|
public readonly vaultPluginCode: VaultPluginErrorCode;
|
|
|
|
public constructor(
|
|
code: VaultPluginErrorCode,
|
|
message: string,
|
|
options?: SuaveplanErrorOptions
|
|
) {
|
|
super(code, message, options);
|
|
this.vaultPluginCode = code;
|
|
}
|
|
}
|