# Interactors in Hanami 2.1

**URL:** <https://discourse.hanakai.org/t/interactors-in-hanami-2-1/965>\
**Category:** questions\
**Created:** [May 9, 2024, 7:07am UTC](https://discourse.hanakai.org/t/interactors-in-hanami-2-1/965 "2024-05-09T07:07:04Z")\
**Posts on this page:** 1\
**Showing post:** 9

<div class="post-metadata">

**Author:** ![alassek](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/alassek/32/532_2.png) [@alassek](https://discourse.hanakai.org/u/alassek)\
**Post date:** [May 17, 2024, 10:22pm UTC](https://discourse.hanakai.org/t/interactors-in-hanami-2-1/965/9 "2024-05-17T22:22:46Z")

</div>

Here’s a helper method I make extensive use of: it’s called `either` and its purpose is to facilitate wrapping error results in tuples.

My Failure results always take the form of `Failure[:error_name, *args]` unless I am wrapping an exception. This makes pattern-matching errors from the outside much easier.

```ruby
  # Utility helper to avoid .to_monad.or {} chaining
  #
  # @param [#to_monad] result, Dry::Monads::Result or object that responds to `to_monad`
  # @param [Dry::Monads::Result::Failure, #to_proc, { :error => Symbol }] error
  #
  # @example With Yield
  # user = yield fetch_user.(id).or { |err| Failure[:not_found, err] }
  #
  # @example With Either
  # user = either fetch_user.(id), Failure(:not_found)
  # user = either fetch_user.(id), ->(err) { Failure[:not_found, err] }
  # user = either fetch_user.(ud), error: :not_found
  #
  # @raise [Dry::Monads::Do::Halt]
  #
  # @return the unwrapped successful value
  def either(result, error)
    failure =
      case error
      in { error: error_name }
        proc { |err| Failure[error_name, err] }
      in T::Procable
        error
      else
        proc { error }
      end

    Dry::Monads::Do.bind result.to_monad.or(&failure)
  end

```

`T::Procable` is just a type defined as

```ruby
Procable = Interface(:to_proc)

```

---

_[View the full topic](https://discourse.hanakai.org/t/interactors-in-hanami-2-1/965)._
