Concepts

Errors reference

How to import

typescript
import {
  StateledgerError,
  InvalidTransition,
  GuardRejected,
  OptimisticConcurrencyError,
  StaleSubjectError,
  AdapterError,
} from "@stateledger/core";

Error hierarchy

Every error extends StateledgerError, which extends the built-in Error. Use instanceof for narrow catches, or instanceof StateledgerError for a catch-all branch.

text
Error
  └── StateledgerError
        ├── InvalidTransition
        ├── GuardRejected
        ├── OptimisticConcurrencyError
        ├── StaleSubjectError
        └── AdapterError

InvalidTransition

You called transitionTo(target) but there's no declared transition from the current state to target.

Fields: machine, subjectId, from, to
typescript
try {
  await invoice.transitionTo("paid"); // but current state is "draft"
} catch (err) {
  if (err instanceof InvalidTransition) {
    console.log(`Cannot go from ${err.from} to ${err.to}`);
  }
}

GuardRejected

A guard function you registered threw or returned false to block the transition.

Fields: machine, subjectId, from, to, reason
typescript
try {
  await invoice.transitionTo("paid"); // amount is zero, guard blocks
} catch (err) {
  if (err instanceof GuardRejected) {
    return { ok: false, reason: err.reason };
  }
}

OptimisticConcurrencyError

The optimistic-locking adapter mode detected that another process wrote a transition between your read and your write.

Fields: machine, subjectId, expectedFrom
typescript
try {
  await invoice.transitionTo("paid");
} catch (err) {
  if (err instanceof OptimisticConcurrencyError) {
    // Someone else moved the invoice. Re-read and re-decide.
    const current = await invoice.readCurrent();
    // ...
  }
}

StaleSubjectError

The subject snapshot you passed at .for() time no longer matches the DB (row was updated by someone else since you loaded it).

Fields: machine, subjectId
typescript
try {
  await invoice.transitionTo("paid");
} catch (err) {
  if (err instanceof StaleSubjectError) {
    // Refetch the subject and retry
  }
}

AdapterError

The underlying database call failed. Wraps the original driver error via the standard cause chain.

Fields: message, cause
typescript
try {
  await invoice.transitionTo("paid");
} catch (err) {
  if (err instanceof AdapterError) {
    console.error("DB failure:", err.cause);
  }
}

StateledgerError

Base class for every error above. Catch this if you want to handle any stateledger-originating failure with one branch.

Fields: message
typescript
try {
  await invoice.transitionTo("paid");
} catch (err) {
  if (err instanceof StateledgerError) {
    // Any stateledger-specific failure
  } else {
    throw err; // something else
  }
}