From e2061e571d5f0540e45c1a0c7e5a9cbd2d88d2f1 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Tue, 14 Apr 2026 22:08:59 -0400 Subject: [PATCH 1/2] fix(types): reflect partial failure context construction Signed-off-by: Yordis Prieto --- lib/commanded/event/failure_context.ex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/commanded/event/failure_context.ex b/lib/commanded/event/failure_context.ex index a1097070..4e251e2e 100644 --- a/lib/commanded/event/failure_context.ex +++ b/lib/commanded/event/failure_context.ex @@ -24,11 +24,11 @@ defmodule Commanded.Event.FailureContext do alias Commanded.EventStore.EnrichedMetadata @type t :: %__MODULE__{ - application: Commanded.Application.t(), - handler_name: String.t(), + application: Commanded.Application.app_ref() | nil, + handler_name: String.t() | nil, handler_state: nil | any(), - context: map(), - metadata: EnrichedMetadata.t(), + context: map() | nil, + metadata: EnrichedMetadata.t() | nil, stacktrace: Exception.stacktrace() | nil } From 56551f213080d1e9f983cac8c74cff32fbae0dea Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Tue, 14 Apr 2026 23:07:20 -0400 Subject: [PATCH 2/2] fix(types): keep failure context strict Signed-off-by: Yordis Prieto --- lib/commanded/event/failure_context.ex | 10 ++++--- test/commanded/event/error_handler_test.exs | 32 +++++++++++++++++---- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/lib/commanded/event/failure_context.ex b/lib/commanded/event/failure_context.ex index 4e251e2e..7a9292df 100644 --- a/lib/commanded/event/failure_context.ex +++ b/lib/commanded/event/failure_context.ex @@ -24,14 +24,16 @@ defmodule Commanded.Event.FailureContext do alias Commanded.EventStore.EnrichedMetadata @type t :: %__MODULE__{ - application: Commanded.Application.app_ref() | nil, - handler_name: String.t() | nil, + application: Commanded.Application.app_ref(), + handler_name: String.t(), handler_state: nil | any(), - context: map() | nil, - metadata: EnrichedMetadata.t() | nil, + context: map(), + metadata: EnrichedMetadata.t(), stacktrace: Exception.stacktrace() | nil } + @enforce_keys [:application, :handler_name, :context, :metadata] + defstruct [ :application, :handler_name, diff --git a/test/commanded/event/error_handler_test.exs b/test/commanded/event/error_handler_test.exs index 128fd4f4..cb1c147c 100644 --- a/test/commanded/event/error_handler_test.exs +++ b/test/commanded/event/error_handler_test.exs @@ -9,7 +9,7 @@ defmodule Commanded.Event.ErrorHandlerTest do end test "Stop on error" do - context = %FailureContext{} + context = failure_context() error = {:error, "an error"} result = ErrorHandler.stop_on_error(error, an_event(), context) @@ -18,7 +18,7 @@ defmodule Commanded.Event.ErrorHandlerTest do describe "backoff" do test "the first delay is 1 second" do - context = %FailureContext{context: %{}} + context = failure_context() {:retry, delay, context} = ErrorHandler.backoff(an_error(), an_event(), context, jitter_fn: no_jitter()) @@ -37,7 +37,7 @@ defmodule Commanded.Event.ErrorHandlerTest do end test "backs off exponentially-ish" do - failure_context = %FailureContext{context: %{}} + failure_context = failure_context() expectations = [ {1, 1_000}, @@ -66,7 +66,7 @@ defmodule Commanded.Event.ErrorHandlerTest do test "maxes out at 1 day" do # We should hit the max after 294 failures - context = %FailureContext{context: %{failures: 500}} + context = failure_context(%{failures: 500}) {:retry, actual_delay, _context} = ErrorHandler.backoff(an_error(), an_event(), context, jitter_fn: no_jitter()) @@ -122,5 +122,27 @@ defmodule Commanded.Event.ErrorHandlerTest do defp an_event, do: %Event{id: 123} defp an_error, do: {:error, "Invalid pizza toppings"} defp no_jitter, do: fn -> 0 end - defp failure_context, do: %FailureContext{context: %{}} + + defp failure_context(context \\ %{}) do + %FailureContext{ + application: MyApp.CommandedApp, + handler_name: "MyApp.FailingEventHandler", + handler_state: nil, + context: context, + metadata: %{ + event_id: "0f117f39-3b2f-491e-b39d-9325fd1d19d1", + event_number: 1, + stream_id: "2iO5kHYbIAGW1rrZ7FeHCRMvbT5", + stream_version: 1, + correlation_id: "e9c3b49e-0ac5-44db-8ddb-83835a7c9437", + causation_id: "49d9a83c-8bcd-4fa9-9ccb-3c196717415c", + created_at: ~U[2024-06-25 20:55:24.576545Z], + application: MyApp.CommandedApp, + handler_name: "MyApp.FailingEventHandler", + state: nil, + metadata: %{} + }, + stacktrace: nil + } + end end