first commit
This commit is contained in:
76
docs/persistence/cache/cache-redis/src/errors/errors.md
vendored
Normal file
76
docs/persistence/cache/cache-redis/src/errors/errors.md
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# errors
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the structured error surface for `@suaveplan/cache-redis`. Every failure inside the package — connection drops to the Redis server, individual command rejections, codec round-trip failures, oversized keys, invalid TTL arguments — surfaces as a `RedisCacheError` carrying one of the codes registered in `CACHE_REDIS_CODES`. Consumers programmatically branch on `error.code` rather than parsing free-form messages, and the optional `key` and `command` discriminants pinpoint exactly which command on which key triggered the failure.
|
||||
|
||||
## Features
|
||||
|
||||
- 5-code registry built with `defineCodes("CACHE_REDIS", [...])` so codes serialise identically across OpenTelemetry span events, the wire-format error envelope, and the i18n resolver.
|
||||
- `RedisCacheError` extends `SuaveplanError<CacheRedisCode>` for cause chains, structured `traceId`, and arbitrary `context`.
|
||||
- `key` and `command` discriminants on every error — present whenever a failure originates at a known key or command boundary.
|
||||
- Every code is exercised at a real call site by `errors.test.ts`, satisfying the §13 step 0 reachability gate.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
CACHE_REDIS_CODES,
|
||||
RedisCacheError,
|
||||
} from "@suaveplan/cache-redis/errors";
|
||||
|
||||
try {
|
||||
await cache.set("k", value);
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof RedisCacheError &&
|
||||
err.code === CACHE_REDIS_CODES.CONNECTION_FAILED
|
||||
) {
|
||||
metrics.increment("cache.redis.connection_failure");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
CACHE_REDIS_CODES,
|
||||
RedisCacheError,
|
||||
} from "@suaveplan/cache-redis/errors";
|
||||
|
||||
function classify(err: unknown): "retry" | "fatal" | "ignore" {
|
||||
if (!(err instanceof RedisCacheError)) return "fatal";
|
||||
switch (err.code) {
|
||||
case CACHE_REDIS_CODES.CONNECTION_FAILED:
|
||||
case CACHE_REDIS_CODES.COMMAND_FAILED:
|
||||
return "retry";
|
||||
case CACHE_REDIS_CODES.CODEC_ERROR:
|
||||
return "ignore"; // cache miss is safe
|
||||
case CACHE_REDIS_CODES.KEY_TOO_LONG:
|
||||
case CACHE_REDIS_CODES.INVALID_TTL:
|
||||
return "fatal";
|
||||
default:
|
||||
return "fatal";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
| Export | Kind | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `CACHE_REDIS_CODES` | const | Frozen object mapping reason → `"CACHE_REDIS.<REASON>"` value. |
|
||||
| `CacheRedisCode` | type | Union of the registered code values. |
|
||||
| `RedisCacheError` | class | Extends `SuaveplanError<CacheRedisCode>`. Constructor: `(code, messageKey, options?)` where options may carry `key`, `command`, `cause`, `context`, `traceId`. |
|
||||
| `RedisCacheErrorOptions` | type | `SuaveplanErrorOptions & { key?: string; command?: string }`. |
|
||||
|
||||
Registered codes: `CONNECTION_FAILED`, `COMMAND_FAILED`, `CODEC_ERROR`, `KEY_TOO_LONG`, `INVALID_TTL`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`CONNECTION_FAILED` is intentionally the catch-all for "the underlying `RedisLike` client threw something" — the cache cannot distinguish network errors from server-side `READONLY` rejects without parsing the cause, and most consumers treat both as "retry later." `COMMAND_FAILED` is reserved for failures that originate inside the cache itself — currently only `clear()` without a namespace; future commands that have explicit semantic preconditions will share this code.
|
||||
Reference in New Issue
Block a user