---
title: Interrupt
layout: gem-single
name: dry-effects
---

Interrupt is an effect with the semantics of `raise`/`rescue` or `throw`/`catch`. It's added for consistency and compatibility with other effects. Underneath, it uses `raise` + `rescue` so that application code can detect the bubbling.

### Basic usage

If you know what exceptions are, this should look familiar:

```ruby
require 'dry/effects'

class RunDivision
  include Dry::Effects::Handler.Interrupt(:division_by_zero, as: :catch_zero_division)

  def call
    success, answer = catch_zero_division do
      yield
    end

    if success
      answer
    else
      :error
    end
  end
end

class Divide
  include Dry::Effects.Interrupt(:division_by_zero)

  def call(dividend, divisor)
    if divisor.zero?
      division_by_zero
    else
      dividend / divisor
    end
  end
end

run = RunDivision.new
divide = Divide.new

app = -> a, b { run.() { divide.(a, b) } }

app.(10, 2) # => 5
app.(1, 0) # => :error
```

The handler returns a flag indicating whether there was an interruption. `false` means the block was run without interruption, `true` stands for the code was interrupted at some point.

### Payload

Interruption can have a payload:

```ruby
class Callee
  include Dry::Effects.Interrupt(:halt)

  def call
    halt :foo
  end
end

class Caller
  include Dry::Effects::Handler.Interrupt(:halt, as: :catch_halt)

  def call
    _, result = catch_halt do
      yield
      :bar
    end

    result
  end
end

caller = Caller.new
callee = Callee.new

caller.() { callee.() } # => :foo
caller.() { } # => :bar
```

### Composition

Every Interrupt effect has to have an identifier so that they don't overlap. It's an equivalent of exception types. You can nest handlers with different identifiers; they will work just as you would expect:

```ruby
class Catcher
  include Dry::Effects::Handler(:div_error, as: :catch_div)
  include Dry::Effects::Handler(:sqrt_error, as: :catch_sqrt)

  def call
    _, div_result = catch_div do
      _, sqrt_result = catch_sqrt do
        yield
      end

      sqrt_result
    end

    div_result
  end
end
```