Foundation.ErrorContext (foundation v0.1.0)

Enhanced error context system with proper propagation and debugging support.

Phase 1 Implementation:

  • Nested context support with breadcrumbs
  • Operation tracking and correlation
  • Emergency context recovery
  • Enhanced error propagation patterns

Summary

Functions

Add a breadcrumb to track operation flow.

Add context to an existing error or create a new one. Enhanced version with better error chaining and context preservation.

Add metadata to an existing context.

Create a child context inheriting from a parent context.

Enhance an Error struct with additional context information.

Format breadcrumbs as a human-readable string.

Get the current error context from the process dictionary.

Get the duration of an operation in nanoseconds.

Create a new error context for an operation.

Execute a function with error context tracking.

Types

breadcrumb()

@type breadcrumb() :: %{
  module: module(),
  function: atom(),
  timestamp: integer(),
  metadata: map()
}

context()

@type context() :: t()

t()

@type t() :: %Foundation.ErrorContext{
  breadcrumbs: [breadcrumb()],
  correlation_id: String.t(),
  function: atom(),
  metadata: map(),
  module: module(),
  operation_id: pos_integer(),
  parent_context: t() | nil,
  start_time: integer()
}

Functions

add_breadcrumb(context, module, function, metadata \\ %{})

@spec add_breadcrumb(t(), module(), atom(), map()) :: t()

Add a breadcrumb to track operation flow.

Parameters

  • context: The context to add breadcrumb to
  • module: Module name for the breadcrumb
  • function: Function name for the breadcrumb
  • metadata: Additional metadata for this step

add_context(result, context, additional_info \\ %{})

@spec add_context(term(), t() | map(), map()) :: term()
@spec add_context(:ok, t() | map(), map()) :: :ok
@spec add_context({:ok, term()}, t() | map(), map()) :: {:ok, term()}
@spec add_context({:error, Foundation.Error.t()}, t(), map()) ::
  {:error, Foundation.Error.t()}
@spec add_context({:error, Foundation.Error.t()}, map(), map()) ::
  {:error, Foundation.Error.t()}
@spec add_context({:error, term()}, t(), map()) :: {:error, Foundation.Error.t()}
@spec add_context({:error, term()}, map(), map()) :: {:error, Foundation.Error.t()}

Add context to an existing error or create a new one. Enhanced version with better error chaining and context preservation.

Parameters

  • result: The result to potentially enhance with context
  • context: The context to add
  • additional_info: Additional context information

add_metadata(context, new_metadata)

@spec add_metadata(t(), map()) :: t()

Add metadata to an existing context.

Parameters

  • context: The context to add metadata to
  • new_metadata: Map of metadata to merge

child_context(parent, module, function, metadata \\ %{})

@spec child_context(t(), module(), atom(), map()) :: t()

Create a child context inheriting from a parent context.

Parameters

  • parent: The parent context
  • module: The module for the child operation
  • function: The function for the child operation
  • metadata: Additional metadata for the child context

Examples

iex> child = ErrorContext.child_context(parent, ChildModule, :child_function)
%ErrorContext{parent_context: ^parent, ...}

enhance_error(error, context)

@spec enhance_error(Foundation.Error.t(), t()) :: Foundation.Error.t()
@spec enhance_error(
  {:error, Foundation.Error.t()},
  t()
) :: {:error, Foundation.Error.t()}
@spec enhance_error(
  {:error, term()},
  t()
) :: {:error, Foundation.Error.t()}
@spec enhance_error(term(), t()) :: term()

Enhance an Error struct with additional context information.

Parameters

  • error: The error to enhance
  • context: The context to add to the error

format_breadcrumbs(error_context)

@spec format_breadcrumbs(t()) :: String.t()

Format breadcrumbs as a human-readable string.

Parameters

  • context: The context containing breadcrumbs to format

get_current_context()

@spec get_current_context() :: t() | nil

Get the current error context from the process dictionary.

This is an emergency recovery mechanism for debugging.

get_operation_duration(error_context)

@spec get_operation_duration(t()) :: integer()

Get the duration of an operation in nanoseconds.

Parameters

  • context: The context to calculate duration for

new(module, function, opts \\ [])

@spec new(module(), atom(), keyword()) :: t()

Create a new error context for an operation.

Parameters

  • module: The module where the operation starts
  • function: The function where the operation starts
  • opts: Options including correlation_id, metadata, parent_context

Examples

iex> ErrorContext.new(MyModule, :my_function)
%ErrorContext{module: MyModule, function: :my_function, ...}

with_context(context, fun)

@spec with_context(t(), (-> term())) :: term() | {:error, Foundation.Error.t()}

Execute a function with error context tracking.

Automatically captures exceptions and enhances them with context information.

Parameters

  • context: The context to use for the operation
  • fun: Zero-arity function to execute

Returns

  • The result of the function, or {:error, enhanced_error} on exception