# `Trogon.Commanded.Helpers`
[🔗](https://github.com/straw-hat-team/beam-monorepo/blob/trogon_commanded@v1.0.1/apps/trogon_commanded/lib/trogon/commanded/helpers.ex#L1)

A Swiss Army Knife Helper Module.

# `commanded_dispatch_response`

```elixir
@type commanded_dispatch_response() ::
  :ok
  | {:ok, aggregate_state :: struct()}
  | {:ok, aggregate_version :: non_neg_integer()}
  | {:ok, execution_result :: Commanded.Commands.ExecutionResult.t()}
  | {:error, :unregistered_command}
  | {:error, :consistency_timeout}
  | {:error, reason :: term()}
```

# `error_context`

```elixir
@type error_context() :: Commanded.Event.FailureContext.t() | map()
```

# `cast_to`

```elixir
@spec cast_to(target :: map(), source :: map(), keys :: [Map.key()]) :: map()
```

Copy the information from the `source` map into the given `target` map.

    iex> Trogon.Commanded.Helpers.cast_to(%{}, %{name: "ubi-wan", last_name: "kenobi"}, [:last_name])
    %{last_name: "kenobi"}

# `ignore_error`

```elixir
@spec ignore_error(result :: commanded_dispatch_response(), [{:error, any()}]) ::
  commanded_dispatch_response()
```

Ignores a specific error from a command dispatch result.

This function takes a dispatch result and an error term. If the result represents an error that matches the provided
error term, the function returns `:ok`. Otherwise, it returns the original result.

This is useful when an error condition should be treated as a successful operation under specific circumstances.

## Examples

    iex> Trogon.Commanded.Helpers.ignore_error({:error, :idempotency_failure}, :idempotency_failure)
    :ok

    iex> Trogon.Commanded.Helpers.ignore_error({:error, :something_went_wrong}, :idempotency_failure)
    {:error, :something_went_wrong}

    iex> Trogon.Commanded.Helpers.ignore_error(:ok, :idempotency_failure)
    :ok

    iex> Trogon.Commanded.Helpers.ignore_error({:ok, %{name: "Billy"}}, :idempotency_failure)
    {:ok, %{name: "Billy"}}

# `increase_failure_counter`

```elixir
@spec increase_failure_counter(failure_context :: Commanded.Event.FailureContext.t()) ::
  map()
```

Increase the failure counter from `t:Commanded.Event.FailureContext.t/0` context by one.

      iex> Trogon.Commanded.Helpers.increase_failure_counter(%Commanded.Event.FailureContext{context: %{failures_count: 1}})
      %{failures_count: 2}

# `skip_or_retry`

```elixir
@spec skip_or_retry(
  tuple_response :: commanded_dispatch_response(),
  context :: error_context()
) ::
  :skip | {:retry, error_context()}
```

Returns `skip` or a `retry` response.

When the `c:Commanded.Application.dispatch/1` or `c:Commanded.Application.dispatch/2` returns an `:skip` otherwise,
returns a `:retry` response. Useful when you are doing error handling in your `c:Commanded.Event.Handler.error/3`.

    iex> success_dispatch = fn _ -> :ok end
    ...> Trogon.Commanded.Helpers.skip_or_retry(success_dispatch.(%{}), %{})
    :skip

    iex> success_dispatch = fn _ -> {:ok, %{}} end
    ...> Trogon.Commanded.Helpers.skip_or_retry(success_dispatch.(%{}), %{})
    :skip

    iex> failure_dispatch = fn _ -> {:error, :ooops} end
    ...> Trogon.Commanded.Helpers.skip_or_retry(failure_dispatch.(%{}), %{failures: 1})
    {:retry, %{failures: 1}}

# `skip_or_retry`

```elixir
@spec skip_or_retry(
  tuple_response :: commanded_dispatch_response(),
  delay :: non_neg_integer(),
  context :: error_context()
) :: :skip | {:retry, non_neg_integer(), error_context()}
```

Returns `skip` or a `retry` response with a given delay.

When the `c:Commanded.Application.dispatch/1` or `c:Commanded.Application.dispatch/2` returns an `:skip` otherwise,
returns a `:retry` response. Useful when you are doing error handling in your `c:Commanded.Event.Handler.error/3`.

    iex> success_dispatch = fn _ -> :ok end
    ...> Trogon.Commanded.Helpers.skip_or_retry(success_dispatch.(%{}), 5_000, %{})
    :skip

    iex> success_dispatch = fn _ -> {:ok, %{}} end
    ...> Trogon.Commanded.Helpers.skip_or_retry(success_dispatch.(%{}), 5_000, %{})
    :skip

    iex> failure_dispatch = fn _ -> {:error, :ooops} end
    ...> Trogon.Commanded.Helpers.skip_or_retry(failure_dispatch.(%{}), 5_000, %{failures: 1})
    {:retry, 5_000, %{failures: 1}}

# `struct_from`

```elixir
@spec struct_from(source :: struct(), target :: struct()) :: struct()
@spec struct_from(attrs :: map(), target :: module()) :: struct()
```

Transforms the given `source` map or struct into the `target` struct.

# `tracing_from_metadata`

```elixir
@spec tracing_from_metadata(metadata :: Commanded.Event.Handler.metadata()) :: [
  causation_id: String.t(),
  correlation_id: String.t()
]
```

Returns a keyword list containing the "correlation id" and "causation id" tracing.

    iex> Trogon.Commanded.Helpers.tracing_from_metadata(%{
    ...>   event_id: "26eb06fe-9ba6-4f58-a2dd-2bdba73de4f2",
    ...>   correlation_id: "f634ba94-145c-4fa7-bf7f-0d73dd83b446"
    ...> })
    ...>
    [causation_id: "26eb06fe-9ba6-4f58-a2dd-2bdba73de4f2", correlation_id: "f634ba94-145c-4fa7-bf7f-0d73dd83b446"]

Useful when dispatching commands to copy-forward `t:Commanded.Event.Handler.metadata/0` tracing information.

    defmodule MyProcessor do
        application: MyApp,
      use Commanded.Event.Handler,
        name: "my_processor"

      alias Trogon.Commanded.Helpers

      def handle(%MyEvent{} = event, metadata) do
        MyApp.dispatch(
          %MyCommand{},
          # copy-forward the information
          Helpers.tracing_from_metadata(metadata)
        )
      end
    end

# `tracing_from_metadata`

```elixir
@spec tracing_from_metadata(
  opts :: keyword(),
  metadata :: Commanded.Event.Handler.metadata()
) :: [
  causation_id: String.t(),
  correlation_id: String.t()
]
```

Adds the "correlation id" and "causation id" tracing to an existing keyword list configuration option.

    iex> Trogon.Commanded.Helpers.tracing_from_metadata([timeout: 30_000], %{
    ...>   event_id: "26eb06fe-9ba6-4f58-a2dd-2bdba73de4f2",
    ...>   correlation_id: "f634ba94-145c-4fa7-bf7f-0d73dd83b446"
    ...> })
    ...>
    [timeout: 30_000, causation_id: "26eb06fe-9ba6-4f58-a2dd-2bdba73de4f2", correlation_id: "f634ba94-145c-4fa7-bf7f-0d73dd83b446"]

Useful when dispatching commands to copy-forward the `t:Commanded.Event.Handler.metadata/0` tracing information and
wants to also add other keyword list options.

    defmodule MyProcessor do
      use Commanded.Event.Handler,
        application: MyApp,
        name: "my_processor"

      alias Trogon.Commanded.Helpers

      def handle(%MyEvent{} = event, metadata) do
        MyApp.dispatch(
          %MyCommand{},
          # copy-forward the information
          Helpers.tracing_from_metadata([timeout: 30_000], metadata)
        )
      end
    end

---

*Consult [api-reference.md](api-reference.md) for complete listing*
