Aditya M P Aditya M P - 2 months ago 12
Ruby Question

How can this lambda be rewritten with a guard clause?

I'm using the following lambda, gathered from the

README
of
Resque::Mailer
(https://github.com/zapnap/resque_mailer):


Resque::Mailer.error_handler = lambda { |mailer, _message, error, action, args|
# Necessary to re-enqueue jobs that receive the SIGTERM signal
if error.is_a?(Resque::TermException)
Resque.enqueue(mailer, action, *args)
else
raise error
end
}


Unfortunately,
rubocop
enabled on the codebase, complains about the
if..else
nature of the method, with the error:
Use a guard clause instead of wrapping the code inside a conditional expression
.

I tried setting up an
unless
here, but so far, the
raise error
would be executed no matter which order I set it up. What's the right way to use a guard clause here?

To wit, the reason I ask this is, the following example seems to indicate that if I do the obvious thing with
unless
, the error will always be raised. Am I understanding this wrong?


Development [10] (main)> class Foo
Development [10] (main)* def bar
Development [10] (main)* puts "Outside unless getting exec" unless 1 == 2
Development [10] (main)* puts "After unless getting exec"
Development [10] (main)* end
Development [10] (main)* end
:bar
Development [11] (main)> Foo.new.bar
Outside unless getting exec
After unless getting exec
nil

Answer

Transforming the condition into an unless should work, and satisfy rubocop:

 Resque::Mailer.error_handler = lambda { |mailer, _message, error, action, args|
    # Necessary to re-enqueue jobs that receive the SIGTERM signal
    raise error unless error.is_a?(Resque::TermException)
    Resque.enqueue(mailer, action, *args)
  }