first commit
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# `error-codes.ts`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the stable error-code registry for `@suaveplan/api-plugin-file-upload`. Each failure path in the plugin throws a `FileUploadError` carrying one of 11 `UPLOAD.*` codes; consumers branch on `error.code` to render localised messages, decide on retry behaviour, or surface user-facing copy. The registry is the single source of truth for every observable failure mode the plugin exposes — the spec, the integration tests, and downstream consumer code all reference it by name.
|
||||
|
||||
## Features
|
||||
|
||||
- 11 codes registered via `defineCodes("UPLOAD", [...])` so the cause chain, OTel span events, and i18n keys all share the same string prefix.
|
||||
- `FileUploadError` extends `SuaveplanError<UploadErrorCode>` for typed `instanceof` narrowing.
|
||||
- Public constructor so call sites in routes, the assembler, and the storage adapters can throw directly without a factory helper.
|
||||
- Documented per-code semantics so reviewers can confirm every `### Requirement` in the spec maps to exactly one production call site.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
FileUploadError,
|
||||
UPLOAD_CODES,
|
||||
} from "@suaveplan/api-plugin-file-upload/error-codes/error-codes";
|
||||
|
||||
if (size > limit) {
|
||||
throw new FileUploadError(
|
||||
UPLOAD_CODES.TOO_LARGE,
|
||||
`Upload exceeds singleShotLimitBytes`,
|
||||
{ context: { statusCode: 413, size, limit } }
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { FileUploadError } from "@suaveplan/api-plugin-file-upload";
|
||||
|
||||
try {
|
||||
await uploadService.complete(id, declaredHash, principalId);
|
||||
} catch (err) {
|
||||
if (err instanceof FileUploadError) {
|
||||
switch (err.uploadCode) {
|
||||
case "UPLOAD.HASH_MISMATCH":
|
||||
return c.json({ retry: true, reason: "hash-mismatch" }, 422);
|
||||
case "UPLOAD.INCOMPLETE":
|
||||
return c.json({ retry: true, reason: "missing-chunks" }, 409);
|
||||
default:
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `UPLOAD_CODES` — readonly registry of 11 string constants prefixed `UPLOAD.`.
|
||||
- `UploadErrorCode` — union type derived from `UPLOAD_CODES` values.
|
||||
- `FileUploadError extends SuaveplanError<UploadErrorCode>` — concrete error class. Constructor signature `(code: UploadErrorCode, message: string, options?: SuaveplanErrorOptions)`. Carries an `uploadCode` field mirroring `code` for ergonomic narrowing.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The registry is intentionally closed at 11 codes; adding a new code requires bumping the spec delta and threading the new code through a real production path. This is enforced by `error-codes.spec-conformance.test.ts`.
|
||||
- `cause` carries the original `ZodError` for `INVALID_INPUT` and the underlying `Error` for `STORAGE_FAILURE`. Consumers may walk the cause chain via `SuaveplanError.traverseCauses()` from `@suaveplan/error`.
|
||||
- `context.statusCode` is set by every throw site so the `@suaveplan/api` error-handler translates it to the right HTTP status without per-code mapping at the handler layer.
|
||||
Reference in New Issue
Block a user