Skip to main content

Stream Errors

The Stream module provides Effect-wrapped error types for streaming operations in voltaire-effect. These errors are used by both EventStream and BlockStream for consistent error handling across all streaming infrastructure.

Overview

Stream errors represent failures that can occur during streaming operations:
  • Abort errors: When streams are cancelled via AbortSignal
  • Range errors: When RPC providers reject block range requests
  • Reorg errors: When chain reorganizations exceed tracked history
All errors extend voltaire’s base error classes and are compatible with Effect’s error channel.

Error Types

StreamAbortedError

Base class for stream abort errors. Thrown when an AbortSignal is triggered during stream operations.
import { Effect } from 'effect';
import * as Stream from 'voltaire-effect/stream';

const aborted = new Stream.StreamAbortedError("Custom abort message");
// aborted.name === "StreamAbortedError"

EventStreamAbortedError

Thrown when an EventStream operation is aborted.
import * as Stream from 'voltaire-effect/stream';

const error = new Stream.EventStreamAbortedError();
// error.message === "Event stream was aborted"

BlockStreamAbortedError

Thrown when a BlockStream operation is aborted.
import * as Stream from 'voltaire-effect/stream';

const error = new Stream.BlockStreamAbortedError();
// error.message === "Block stream was aborted"

BlockRangeTooLargeError

Thrown when an RPC provider rejects a request because the block range is too large.
import * as Stream from 'voltaire-effect/stream';

const error = new Stream.BlockRangeTooLargeError(18000000n, 19000000n);
// error.message === "Block range too large: 18000000 to 19000000"
// error.fromBlock === 18000000n
// error.toBlock === 19000000n

UnrecoverableReorgError

Thrown when a chain reorganization extends beyond tracked block history. This indicates a “deep reorg” where recovery is not possible without resyncing.
import * as Stream from 'voltaire-effect/stream';

const error = new Stream.UnrecoverableReorgError(100n, 50n);
// error.message === "Unrecoverable reorg: depth 100 exceeds tracked history of 50 blocks"
// error.reorgDepth === 100n
// error.trackedDepth === 50n

Effect Integration

Stream errors work seamlessly with Effect’s error handling using Effect.catchTag for precise error recovery:
import { Effect, pipe } from 'effect';
import * as Stream from 'voltaire-effect/stream';

// Using Effect.catchTag for specific error handling
const program = pipe(
  someStreamOperation(),
  Effect.catchTag("BlockRangeTooLargeError", (error) =>
    Effect.gen(function* () {
      yield* Effect.logWarning(`Range too large: ${error.fromBlock} to ${error.toBlock}`);
      // Retry with smaller range
      return yield* retryWithSmallerRange(error.fromBlock, error.toBlock);
    })
  ),
  Effect.catchTag("UnrecoverableReorgError", (error) =>
    Effect.gen(function* () {
      yield* Effect.logError(`Deep reorg: depth ${error.reorgDepth} exceeds ${error.trackedDepth}`);
      return yield* resyncFromScratch();
    })
  ),
  Effect.catchTag("BlockStreamAbortedError", () =>
    Effect.logInfo("Block stream cancelled gracefully")
  ),
  Effect.catchTag("EventStreamAbortedError", () =>
    Effect.logInfo("Event stream cancelled gracefully")
  )
);

Exhaustive Error Handling

For exhaustive pattern matching over all stream errors:
import { Effect, Match } from 'effect';
import * as Stream from 'voltaire-effect/stream';

const handleStreamError = (error: Stream.StreamError) =>
  Match.value(error).pipe(
    Match.tag("BlockRangeTooLargeError", (e) => 
      Effect.logWarning(`Range ${e.fromBlock}-${e.toBlock} too large`)
    ),
    Match.tag("UnrecoverableReorgError", (e) => 
      Effect.logError(`Deep reorg detected, depth: ${e.reorgDepth}`)
    ),
    Match.tag("BlockStreamAbortedError", () => 
      Effect.log("Block stream aborted")
    ),
    Match.tag("EventStreamAbortedError", () => 
      Effect.log("Event stream aborted")
    ),
    Match.tag("StreamAbortedError", () => 
      Effect.log("Stream aborted")
    ),
    Match.exhaustive
  );

Type Union

The StreamError type is a union of all stream error types for exhaustive pattern matching:
import * as Stream from 'voltaire-effect/stream';

type StreamError = Stream.StreamError;
// = StreamAbortedError | EventStreamAbortedError | BlockStreamAbortedError 
//   | BlockRangeTooLargeError | UnrecoverableReorgError

See Also