Dispatch

Error Handling

Sentinel errors and how Dispatch surfaces problems.

Dispatch defines a set of sentinel errors in the root package. Use errors.Is to check for specific conditions.

Sentinel errors

import "github.com/xraph/dispatch"

var (
    // Store errors
    ErrNoStore         = errors.New("dispatch: no store configured")
    ErrStoreClosed     = errors.New("dispatch: store closed")
    ErrMigrationFailed = errors.New("dispatch: migration failed")

    // Not found errors
    ErrJobNotFound      = errors.New("dispatch: job not found")
    ErrWorkflowNotFound = errors.New("dispatch: workflow not found")
    ErrRunNotFound      = errors.New("dispatch: run not found")
    ErrCronNotFound     = errors.New("dispatch: cron entry not found")
    ErrDLQNotFound      = errors.New("dispatch: dlq entry not found")
    ErrEventNotFound    = errors.New("dispatch: event not found")
    ErrWorkerNotFound   = errors.New("dispatch: worker not found")

    // Conflict errors
    ErrJobAlreadyExists = errors.New("dispatch: job already exists")
    ErrDuplicateCron    = errors.New("dispatch: duplicate cron entry")

    // State errors
    ErrInvalidState       = errors.New("dispatch: invalid state transition")
    ErrMaxRetriesExceeded = errors.New("dispatch: max retries exceeded")

    // Cluster errors
    ErrLeadershipLost = errors.New("dispatch: leadership lost")
    ErrNotLeader      = errors.New("dispatch: not the leader")
)

Checking errors

err := engine.Enqueue(ctx, eng, SendEmail, input)
if errors.Is(err, dispatch.ErrNoStore) {
    // dispatcher has no store configured
}

Wrapping convention

Subsystems wrap sentinels with fmt.Errorf and %w:

return fmt.Errorf("%w: job %s", dispatch.ErrJobNotFound, jobID)

Cluster errors

When running distributed workers, leadership-related errors may surface during cron scheduling or stale-job recovery:

if errors.Is(err, dispatch.ErrLeadershipLost) {
    // another worker took leadership mid-operation; safe to ignore
}
if errors.Is(err, dispatch.ErrNotLeader) {
    // this worker is not the leader; skip leader-only operations
}

On this page