first commit
This commit is contained in:
52
docs/security-stack/security/vault/src/errors/vault-error.md
Normal file
52
docs/security-stack/security/vault/src/errors/vault-error.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# VaultError
|
||||
|
||||
## Purpose
|
||||
|
||||
`vault-error.ts` defines `VaultError`, the concrete `SuaveplanError` subclass thrown by every public path in `@suaveplan/vault`. It binds the runtime instance to a `VaultErrorCode` from the stable code registry and tags every instance with a unique brand symbol so duck-typed peers cannot impersonate a `VaultError` across module or worker boundaries.
|
||||
|
||||
This package follows the same shape as `@suaveplan/vault-sync`'s `VaultSyncError` and `@suaveplan/crypto-vault`'s `CryptoVaultError`: subclass `SuaveplanError` once, parameterise on the package's code-union, and add a brand-symbol type guard. Consumer code in the password-manager UI, browser extension, and desktop shell can pattern-match on `err instanceof VaultError` and switch over `err.code` without worrying about colliding with a foreign error class.
|
||||
|
||||
## Features
|
||||
|
||||
- Subclass of `SuaveplanError<VaultErrorCode>` — inherits structured fields (`code`, `messageKey`, `cause`, `context`).
|
||||
- Unique-symbol brand attached at construction — survives `instanceof` failures across realms.
|
||||
- `VaultError.is(value)` static type guard — safe across iframe / worker boundaries.
|
||||
- Forwards `SuaveplanErrorOptions` to the base class so `cause`, `context`, and i18n metadata flow through unchanged.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { VAULT_CODES, VaultError } from "@suaveplan/vault/errors";
|
||||
|
||||
throw new VaultError(VAULT_CODES.LOCKED, "error.vault.locked");
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { VAULT_CODES, VaultError } from "@suaveplan/vault/errors";
|
||||
|
||||
try {
|
||||
await vault.items.create({ title: "" });
|
||||
} catch (err) {
|
||||
if (VaultError.is(err) && err.code === VAULT_CODES["ITEM.VALIDATION_FAILED"]) {
|
||||
// Surface the missing-field reason from `err.context` to the form.
|
||||
showValidationErrors(err.context);
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `class VaultError extends SuaveplanError<VaultErrorCode>` — concrete error class.
|
||||
- `constructor(code: VaultErrorCode, messageKey: string, options?: SuaveplanErrorOptions)` — instantiate with one of the codes in `VAULT_CODES` and an i18n message key.
|
||||
- `static is(value: unknown): value is VaultError` — brand-aware type guard.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The brand symbol is a `unique symbol` declared module-locally; it cannot be reproduced from outside this file even with full source access.
|
||||
- The constructor sets the brand property after calling `super()` so the inherited `code`, `messageKey`, and `context` fields are populated normally.
|
||||
- The static `is(value)` guard checks both `instanceof VaultError` and the brand property — this defends against subclasses or polyfills that satisfy `instanceof` but were not minted by this package.
|
||||
- Throwing `VaultError` is the only way the package signals a recoverable failure to callers; lifecycle, item, attachment, share, sync, and opaque-handle paths all use this class.
|
||||
Reference in New Issue
Block a user