Skip to content

Instantly share code, notes, and snippets.

@slashdotdash
Created September 11, 2019 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slashdotdash/db5297a9444ba697b4aca9c3964f786f to your computer and use it in GitHub Desktop.
Save slashdotdash/db5297a9444ba697b4aca9c3964f786f to your computer and use it in GitHub Desktop.
Commanded event handler default error handling

Commanded event handler default error handling

Implement a default event handler error/3 callback function with optional support for retrying failed events before eventually skipping it.

Usage

defmodule MyApp.ExampleHandler do
  use Commanded.Event.Handler, name: __MODULE__
  use Commanded.Event.DefaultErrorHandling, retries: 3
end
defmodule Commanded.Event.DefaultErrorHandling do
defmacro __using__(opts \\ []) do
quote do
@retries unquote(Keyword.get(opts, :retries, 0))
require Logger
alias Commanded.Event.FailureContext
def error({:error, error}, event, %FailureContext{} = failure_context) do
%FailureContext{context: context, metadata: metadata} = failure_context
event_id = Map.get(metadata, :event_id)
event_number = Map.get(metadata, :event_number)
context = Map.update(context, :failures, 1, fn failures -> failures + 1 end)
case Map.get(context, :failures) do
failures when failures > @retries ->
Logger.error(fn ->
"Skipping event " <>
inspect(event_id) <>
" (##{inspect(event_number)}) due to too many failures: " <> inspect(event)
end)
# Skip problematic event after too many failures
:skip
_ ->
Logger.warn(fn ->
"Failed to handle event " <>
inspect(event_id) <> " (##{inspect(event_number)}) due to: " <> inspect(error)
end)
# Retry event, failure count is included in context map
{:retry, context}
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment