Skip to content

Commit

Permalink
Prevent duplicate invocation of the error callback when guarding an i…
Browse files Browse the repository at this point in the history
…nstance method
  • Loading branch information
Drenmi committed Jun 27, 2022
1 parent c50cbf9 commit b8c40ab
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 12 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 0.9.2

### Bug fixes

- Prevent duplicate invocation of the error callback when guarding an instance
method.

## 0.9.1

### Bug fixes
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
PATH
remote: .
specs:
stimpack (0.9.1)
stimpack (0.9.2)
activesupport (>= 6.1)

GEM
remote: https://rubygems.org/
specs:
activesupport (7.0.2.2)
activesupport (7.0.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
ast (2.4.2)
concurrent-ruby (1.1.9)
concurrent-ruby (1.1.10)
diff-lcs (1.4.4)
i18n (1.10.0)
concurrent-ruby (~> 1.0)
Expand Down
6 changes: 5 additions & 1 deletion lib/stimpack/result_monad/guard_clause.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ module GuardCatcher
def call
super
rescue GuardFailed => e
run_callback(:error)
# Avoid running the error callback in the case where it was already
# called by using `#error` in an instance method that is guarded
# against in the `#call` method.
#
run_callback(:error) unless e.result.klass == self.class

e.result
end
Expand Down
2 changes: 1 addition & 1 deletion lib/stimpack/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Stimpack
VERSION = "0.9.1"
VERSION = "0.9.2"
end
48 changes: 41 additions & 7 deletions spec/stimpack/result_monad/guard_clause_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,21 @@
RSpec.describe Stimpack::ResultMonad::GuardClause do
subject(:service) { klass }

let(:instance) { service.new }
let(:instance) { service.new(private_error: private_error) }
let(:private_error) { false }

let(:klass) do
Class.new do
include Stimpack::ResultMonad

result :foo

def initialize(private_error: false)
@private_error = private_error
end

attr_reader :private_error

def success_result(**options)
success(**options)
end
Expand All @@ -27,9 +34,12 @@ def self.to_s

def call
guard :foo

bar_result = guard { bar }
baz_result = guard { baz }

guard { qux } if private_error

success(foo: bar_result + baz_result)
rescue StandardError
error(errors: "Something went wrong, but not a guard fail.")
Expand All @@ -48,13 +58,18 @@ def bar
def baz
pass("Baz")
end

def qux
error(errors: ["Same class error"])
end
end
end

let(:inner_service_error) do
double(
Stimpack::ResultMonad::Result,
failed?: true,
klass: "Foo",
errors: ["Inner error"]
)
end
Expand All @@ -63,6 +78,7 @@ def baz
double(
Stimpack::ResultMonad::Result,
failed?: false,
klass: "Foo",
unwrap!: "Foo",
errors: nil
)
Expand Down Expand Up @@ -121,15 +137,33 @@ def baz
end

describe ".before_error" do
before do
allow(instance).to receive(:inspect)
allow(instance).to receive(:foo).and_return(inner_service_error)
context "when inner service fails" do
before do
allow(instance).to receive(:inspect)
allow(instance).to receive(:foo).and_return(inner_service_error)

service.before_error { inspect }
service.before_error { inspect }

instance.()
end

instance.()
it { expect(instance).to have_received(:inspect).once }
end

it { expect(instance).to have_received(:inspect).once }
context "when passing an error from an instance method" do
let(:private_error) { true }

before do
allow(instance).to receive(:inspect)
allow(instance).to receive(:foo).and_return(inner_service_success)
allow(instance).to receive(:bar).and_return(inner_service_success)

service.before_error { inspect }

instance.()
end

it { expect(instance).to have_received(:inspect).once }
end
end
end

0 comments on commit b8c40ab

Please sign in to comment.