first commit
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# error-codes
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the canonical `STORAGE_URI_CODES` registry and the `StorageUriError`
|
||||
class for the `@suaveplan/storage-uri` package. Every error surfaced by the
|
||||
resolver — whether raised directly or re-wrapped from a downstream adapter —
|
||||
carries one of these eight codes and the `uri`/`scheme` discriminants so
|
||||
operators can correlate failures to the offending request without parsing
|
||||
free-form message text.
|
||||
|
||||
The registry is built via `defineCodes("STORAGE_URI", [...] as const)` from
|
||||
`@suaveplan/error`, which produces the runtime strings
|
||||
`STORAGE_URI.UNKNOWN_SCHEME`, `STORAGE_URI.INVALID_URI`,
|
||||
`STORAGE_URI.SCHEME_CONFLICT`, `STORAGE_URI.NOT_FOUND`,
|
||||
`STORAGE_URI.LIST_UNSUPPORTED`, `STORAGE_URI.WRITE_UNSUPPORTED`,
|
||||
`STORAGE_URI.ABORTED`, and `STORAGE_URI.ADAPTER_ERROR`.
|
||||
|
||||
## Features
|
||||
|
||||
- Frozen 8-code registry, type-narrowing `instanceof` via the
|
||||
literal-typed `TCode` parameter on `SuaveplanError`.
|
||||
- `uri` and `scheme` discriminants on every `StorageUriError` instance.
|
||||
- `cause` chain preserved when the resolver re-wraps an adapter throwable as
|
||||
`ADAPTER_ERROR` or `WRITE_UNSUPPORTED`.
|
||||
- Zero runtime dependencies beyond `@suaveplan/error`.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { STORAGE_URI_CODES, StorageUriError } from "@suaveplan/storage-uri/error-codes";
|
||||
|
||||
throw new StorageUriError(
|
||||
STORAGE_URI_CODES.UNKNOWN_SCHEME,
|
||||
"no plugin for ftp",
|
||||
{ uri: "ftp://x/y", scheme: "ftp" },
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
try {
|
||||
await resolver.read("file:///missing");
|
||||
} catch (err) {
|
||||
if (err instanceof StorageUriError) {
|
||||
if (err.code === STORAGE_URI_CODES.NOT_FOUND) return undefined;
|
||||
if (err.code === STORAGE_URI_CODES.ADAPTER_ERROR) {
|
||||
// Trace back to the original adapter code via the cause chain.
|
||||
console.error("upstream failure", err.cause);
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `STORAGE_URI_CODES` — frozen record `{ UNKNOWN_SCHEME, INVALID_URI,
|
||||
SCHEME_CONFLICT, NOT_FOUND, LIST_UNSUPPORTED, WRITE_UNSUPPORTED, ABORTED,
|
||||
ADAPTER_ERROR }`. Each value is the fully-qualified `STORAGE_URI.<REASON>`
|
||||
string.
|
||||
- `type StorageUriErrorCode` — union of every value in the registry.
|
||||
- `interface StorageUriErrorOptions extends SuaveplanErrorOptions` — adds
|
||||
`uri?: string` and `scheme?: string`.
|
||||
- `class StorageUriError extends SuaveplanError<StorageUriErrorCode>` —
|
||||
exposes `readonly uri`, `readonly scheme`, inherits `code`, `cause`,
|
||||
`context`, `traceId`, `timestamp` from the base class.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`defineCodes` returns a frozen object via `Object.create(null)` so the
|
||||
registry has no prototype-pollution surface. `StorageUriError`'s constructor
|
||||
mirrors `StorageHttpError` and `StorageFileError` — `uri`/`scheme` are
|
||||
captured by direct field assignment rather than through a context map so
|
||||
they survive structured-clone serialisation. The `name` is set to
|
||||
`"StorageUriError"` explicitly so `err.name` is stable across V8/JSC/SM
|
||||
where `new.target.name` could otherwise be munged by minification.
|
||||
Reference in New Issue
Block a user