Skip to content

Shutdown lifecycle

mermaid
sequenceDiagram
  participant OS
  participant LC as lastcall
  participant H as Handlers

  OS->>LC: SIGTERM
  LC->>LC: beforeShutdown event
  loop Each phase
    LC->>H: run batch (parallel per priority)
    H-->>LC: complete / error / timeout
  end
  LC->>LC: afterShutdown event
  LC->>OS: process.exit(code)

Trigger sources

SourceHow
SIGTERM / SIGINT / SIGHUPAutomatic (configurable)
Manualawait lastcall.shutdown('reason')
Testinglastcall.simulateSignal('SIGTERM')
uncaughtExceptioncaptureUncaughtException: true
unhandledRejectioncaptureUnhandledRejection: true

Exit codes

CodeMeaning
0All handlers completed (non-critical failures OK)
1Critical handler failed, timed out, or global timeout

Idempotency

If shutdown is already in progress, additional signals and shutdown() calls return the same promise.

Global timeout

shutdownTimeoutMs (default 30s) aborts the entire shutdown. Handlers receive abortSignal on their context.

Handler context

Every handler receives:

ts
interface HandlerContext {
  reason: string; // why shutdown started
  signal?: ShutdownSignal;
  phase: ShutdownPhase;
  abortSignal: AbortSignal;
}