Initial Commit
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# job-scheduler-error
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Defines the typed error registry and `JobSchedulerError` class for `@suaveplan/job-scheduler`. The package emits exactly three of its own codes — `JOB_SCHEDULER.JOB_NOT_FOUND`, `JOB_SCHEDULER.EXECUTION_FAILED`, and `JOB_SCHEDULER.TIMEOUT`. Every other failure (cron syntax, retry exhaustion, abort) propagates with the originating package's error code unchanged so consumers can branch on the structural cause without scheduler middleware obscuring it.
|
||||
|
||||
## Features
|
||||
|
||||
- Frozen `JOB_SCHEDULER_CODES` registry built via `defineCodes` from `@suaveplan/error`.
|
||||
- `JobSchedulerError` class extending `SuaveplanError<JobSchedulerErrorCode>` with runtime code validation at the constructor boundary.
|
||||
- `registerJobSchedulerErrorCodes()` idempotent side-effect probe returning the registered count.
|
||||
- Eager registration on module load so consumers do not need to call the registration function manually.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
JOB_SCHEDULER_CODES,
|
||||
JobSchedulerError,
|
||||
} from "@suaveplan/job-scheduler";
|
||||
|
||||
throw new JobSchedulerError(
|
||||
JOB_SCHEDULER_CODES.JOB_NOT_FOUND,
|
||||
"job_scheduler.job_not_found",
|
||||
{ context: { jobId: "abc-123" } }
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
JobSchedulerError,
|
||||
JOB_SCHEDULER_CODES,
|
||||
registerJobSchedulerErrorCodes,
|
||||
} from "@suaveplan/job-scheduler";
|
||||
|
||||
// Idempotent probe useful in DI containers and tree-shake audits.
|
||||
const codeCount = registerJobSchedulerErrorCodes();
|
||||
if (codeCount !== 3) {
|
||||
throw new Error("expected exactly three JOB_SCHEDULER codes");
|
||||
}
|
||||
|
||||
try {
|
||||
// ...
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof JobSchedulerError &&
|
||||
err.code === JOB_SCHEDULER_CODES.TIMEOUT
|
||||
) {
|
||||
// Surface timeout-specific UX without leaking other failure modes.
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `JOB_SCHEDULER_CODES: { JOB_NOT_FOUND, EXECUTION_FAILED, TIMEOUT }` — frozen string-valued constants.
|
||||
- `type JobSchedulerErrorCode` — union of the three values above.
|
||||
- `class JobSchedulerError extends SuaveplanError<JobSchedulerErrorCode>` — constructor `(code, messageKey, options?)`; throws `TypeError` when `code` is not a registered value.
|
||||
- `registerJobSchedulerErrorCodes(): number` — returns the frozen registry size (always `3`).
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The runtime guard inside the constructor is the only defence against unregistered codes once the type system is erased (e.g. across a Worker boundary, an RPC, or a `JSON.parse`). Pre-erasure consumers get a compile-time refusal from the literal union; post-erasure consumers get a `TypeError` at construction time. The package deliberately keeps the registry tiny — three codes — because every other failure mode in the scheduler has a more specific home: cron parse errors live in `CRON.*`, retry exhaustion lives in `RETRY.*`, and aborts surface as `DOMException("AbortError")` per the platform contract. Expanding this registry without a matching `proposal.md` amendment is a contract break.
|
||||
Reference in New Issue
Block a user