Class ArvoEventHandler<TContract>

ArvoEventHandler is the core component for processing events in the Arvo system. It enforces contracts between services by ensuring that all events follow their specified formats and rules.

The handler is built on two fundamental patterns: Meyer's Design by Contract and Fowler's Tolerant Reader. It binds to an ArvoContract that defines what events it can receive and send across all versions. This versioning is strict - the handler must implement every version defined in its contract, or it will fail both at compile time and runtime.

Following the Tolerant Reader pattern, the handler accepts any incoming event but only processes those that exactly match one of its contract versions. When an event matches, it's handled by the specific implementation for that version. This approach maintains compatibility while ensuring precise contract adherence.

The handler uses Zod for validation, automatically checking both incoming and outgoing events. This means it not only verifies data formats but also applies default values where needed and ensures all conditions are met before and after processing.

Error handling in the handler divides issues into two categories:

  • Violations are serious contract breaches that indicate fundamental problems with how services are communicating. These errors bubble up to the calling code, allowing developers to handle these critical issues explicitly.

  • System Error Events cover normal runtime errors that occur during event processing. These are typically workflow-related issues that need to be reported back to the event's source but don't indicate a broken contract.

const handler = createArvoEventHandler({
contract: userContract,
executionunits: 1,
handler: {
'1.0.0': async ({ event }) => {
// Process event according to contract v1.0.0
},
'2.0.0': async ({ event }) => {
// Process event according to contract v2.0.0
}
}
});

Type Parameters

  • TContract extends ArvoContract

Hierarchy (view full)

Constructors

  • Initializes a new ArvoEventHandler instance with the specified contract and configuration. Validates handler implementations against contract versions during initialization.

    The constructor ensures that handler implementations exist for all supported contract versions and configures OpenTelemetry span attributes for monitoring event handling.

    Type Parameters

    • TContract extends ArvoContract<string, string, Record<`${number}.${number}.${number}`, {
          accepts: ZodTypeAny;
          emits: Record<string, ZodTypeAny>;
      }>, Record<string, any>>

    Parameters

    Returns ArvoEventHandler<TContract>

    When handler implementations are missing for any contract version

Properties

contract: TContract

Contract instance that defines the event schema and validation rules

executionunits: number

Computational cost metric associated with event handling operations

Version-specific event handler implementation map

spanOptions: SpanOptions

OpenTelemetry configuration for event handling spans

Accessors

  • get systemErrorSchema(): ArvoContractRecord<`sys.${string}.error`, ZodObject<{
        errorMessage: ZodString;
        errorName: ZodString;
        errorStack: ZodNullable<ZodString>;
    }, "strip", ZodTypeAny, {
        errorMessage: string;
        errorName: string;
        errorStack: null | string;
    }, {
        errorMessage: string;
        errorName: string;
        errorStack: null | string;
    }>>
  • Provides access to the system error event schema configuration. The schema defines the structure of error events emitted during execution failures.

    Error events follow the naming convention: sys..error For example, a contract handling 'user.created' events will emit error events with the type 'sys.user.created.error'.

    Returns ArvoContractRecord<`sys.${string}.error`, ZodObject<{
        errorMessage: ZodString;
        errorName: ZodString;
        errorStack: ZodNullable<ZodString>;
    }, "strip", ZodTypeAny, {
        errorMessage: string;
        errorName: string;
        errorStack: null | string;
    }, {
        errorMessage: string;
        errorName: string;
        errorStack: null | string;
    }>>

Methods

  • Processes an incoming event according to the handler's contract specifications. This method handles the complete lifecycle of event processing including validation, execution, and error handling, while maintaining detailed telemetry through OpenTelemetry.

    The execution follows a careful sequence to ensure reliability: First, it validates that the event matches the handler's contract type. Then it extracts and validates the event's schema version, defaulting to the latest version if none is specified. After validation passes, it executes the version-specific handler function and processes its output into new events.

    The method handles routing through three distinct paths:

    • For successful execution, events are routed based on handler output or configuration.
      • The 'to' field in the handler's result (if specified)
      • The 'redirectto' field from the source event (if present)
      • Falls back to the source event's 'source' field
    • For violations (mismatched types, invalid data), errors bubble up to the caller
    • For runtime errors, system error events are created and sent back to the source

    Throughout execution, comprehensive telemetry is maintained through OpenTelemetry spans, tracking the complete event journey including validation steps, processing time, and any errors that occur. This enables detailed monitoring and debugging of the event flow.

    Parameters

    • event: ArvoEvent<Record<string, any>, Record<string,
          | null
          | string
          | number
          | boolean>, string>

      The incoming event to process

    • opentelemetry: ArvoEventHandlerOpenTelemetryOptions = ...

      Configuration for OpenTelemetry context inheritance

    Returns Promise<{
        events: ArvoEvent<Record<string, any>, Record<string,
            | null
            | string
            | number
            | boolean>, string>[];
    }>

    Promise resolving to an array of output events or error events

    ContractViolation when input or output event data violates the contract

    ConfigViolation when event type doesn't match contract type or the contract version expected by the event does not exist in handler configuration

    ExecutionViolation for explicitly handled runtime errors