Fail VS. Raise in Ruby:Should We Really Believe the Style Guide

Fail vs. raise in Ruby : Should we really believe the style guide?


use 'raise' for exceptions to be caught, and 'fail' for serious errors which are not meant to be handled

This is not what the official style guide or the link you provided say on the matter.

What is meant here is use raise only in rescue blocks. Aka use fail when you want to say something is failing and use raise when rethrowing an exception.

As for the "does it matter" part - it is not one of the most hardcore strictly followed rules, but you could make the same argument for any convention. You should follow in that order:

  1. Your project style guide
  2. Your company style guide
  3. The community style guide

Ideally, the three should be the same.


Update: As of this PR (December 2015), the convention is to always use raise.

Symbol is passed to 'raise'

Looks like the fail method being used was the warden method:

http://www.rubydoc.info/github/hassox/warden/Warden%2FStrategies%2FBase:fail

Best way to break and return a value

Why do you rescue inside the pay_order method? I'd rescue on the outer loop.
Given the following:

def method_a
10.times do |loop_a|
method_b
end
end

def method_b
5.times do |loop_b|
pay_order
end
end

def pay_order
...
end

I'd rescue inside method_a, for example:

def method_a
10.times do |loop_a|
method_b
end
rescue Stripe::CardError => e
# do whatever. no need to break
end

All the loops are "broken" automatically by the raising of the exception.

If you want to do something with the exception inside the pay_order method, then I would suggest to rescue and raise again:

def pay_order
order.pay
rescue Stripe::CardError => e
# do your stuff
raise e
end

What is the difference between Raising Exceptions vs Throwing Exceptions in Ruby?

I think http://hasno.info/ruby-gotchas-and-caveats has a decent explanation of the difference:

catch/throw are not the same as raise/rescue. catch/throw allows you to quickly exit blocks back to a point where a catch is defined for a specific symbol, raise rescue is the real exception handling stuff involving the Exception object.

Ruby assign a variable or raise error if nil


Basically, what I want to do is this

target_url = @maybe_a || @maybe_b || raise "either a or b must be assigned"

You have to add parentheses to raise to make your code work:

x = a || b || raise("either a or b must be assigned")

It would be "more correct" to use the control-flow operator or instead of ||: (which makes the parentheses optional)

x = a || b or raise "either a or b must be assigned"

This is Perl's "do this or die" idiom which I think is clean and neat. It emphases the fact that raise doesn't provide a result for x – it's called solely for its side effect.

However, some argue that or / and are confusing and shouldn't be used at all. (see rubystyle.guide/#no-and-or-or)

A pattern heavily used by Rails is to have two methods, one without ! which doesn't provide error handling:

def a_or_b
@maybe_a || @maybe_b
end

and one with ! which does:

def a_or_b!
a_or_b || raise("either a or b must be assigned")
end

Then call it via:

target_url = a_or_b!

How to force an RSpec test to fail?

fail/raise will do the trick (they are aliases of each other).

Example

specify "this test fails" do
raise "this is my failure message"
end

Fails with:

1) failing this test fails
Failure/Error: raise "this is my failure message"

RuntimeError:
this is my failure message

Alternatives

If you are thinking of using raise/fail in a spec, you should consider that there are probably more explicit ways of writing your expectation.

Additionally, raise/fail doesn't play well with aggregate_failures because the exception short-circuits the block and won't run any following matchers.

Mark a test as pending

If you need to mark a test as pending to make sure you get back to it, you could use the fail/raise, but you can also use pending.

# Instead of this:
it "should do something" do
# ...
raise "this needs to be implemented"
end

# ✅ Try this:
it "should do something" do
pending "this needs to be implemented"
end

Assert that a block is not called

If you need to ensure a block is not being executed, consider using the yield matchers. For example:

describe "Enumerable#any?" do
# Instead of this:
it "doesn't yield to the block if the collection is empty" do
[].any? { raise "it should not call this block" }
end

# ✅ Try this:
it "doesn't yield to the block if the collection is empty" do
expect { |b| [].any?(&b) }.not_to yield_control
end
end

Does anyone use a style guide for error messages?

Both the iPhone Human Interface Guidelines and the Apple Human Interface Guidelines contain sections on alerts.

Also, the Windows User Experience Interaction Guidelines have information for a few different types of dialogs, including error messages.

(iPhone)

As you compose the required alert title:

  • Keep the title short enough to display on a single line, if possible.
    A long alert title is difficult for
    people to read quickly, and it might
    get truncated or force the alert
    message to scroll.
  • Avoid single-word titles that don’t provide any useful information, such
    as “Error” or “Warning.”
  • When possible, use a sentence fragment. A short, informative
    statement is often easier to
    understand than a complete sentence.
  • Don’t hesitate to be negative. People understand that most alerts
    tell them about problems or warn them
    about dangerous situations. It’s
    better to be negative and direct than
    it is to be positive but oblique.
  • Avoid using “you,” “your,” “me,” and “my” as much as possible. Sometimes,
    text that identifies people directly
    can be ambiguous and can even be
    interpreted as an insult.
  • Use title-style capitalization and no ending punctuation when:
  • The title is a sentence fragment
  • The title consists of a single sentence that is not a question
  • Use sentence-style capitalization and an ending question mark if the
    title consists of a single sentence
    that is a question. In general,
    consider using a question for an alert
    title if it allows you to avoid adding
    a message.
  • Use sentence-style capitalization and appropriate ending punctuation for
    each sentence if the title consists of
    two or more sentences. A two-sentence
    alert title should seldom be
    necessary, although you might consider
    it if it allows you to avoid adding a
    message.

If you provide an optional alert message:

  • Create a short, complete sentence that uses sentence-style
    capitalization and appropriate ending
    punctuation.
  • Avoid creating a message that is too long. If possible, keep the message
    short enough to display on one or two
    lines. If the message is too long it
    will scroll, which is not a good user
    experience.

Avoid lengthening your alert text with descriptions of which button to
tap
, such as “Tap View to see the
information.” Ideally, the combination
of unambiguous alert text and logical
button labels gives people enough
information to understand the
situation and their choices. However,
if you must provide detailed guidance,
follow these guidelines:

  • Be sure to use the word “tap” (not “touch” or “click” or “choose”) to
    describe the selection action.
  • Don’t enclose a button title in quotes, but do preserve its
    capitalization.

-

(Mac)

Alert message text. This text, in emphasized (bold) system font, provides a short, simple summary of the error or condition that summoned the alert. This should be a complete sentence; often it is presented as a question. See “Writing Good Alert Messages” for more information.

Informative text. This text appears in the small system font and provides a fuller description of the situation, its consequences, and ways to get out of it. For example, a warning that an action cannot be undone is an appropriate use of informative text.

A good alert message states clearly what caused the alert to appear and what the user can do about it. Express everything in the user’s vocabulary.

To make the alert really useful, provide a suggestion about what the user can do about the current situation. Even if the alert serves as a notification to the user and no further action is required, provide as much information as needed to describe the situation.

-

(Microsoft)

The characteristics of good error messages

In contrast to the previous bad
examples, good error messages have:

  • A problem. States that a problem occurred.
  • A cause. Explains why the problem occurred.
  • A solution. Provides a solution so that users can fix the problem.

Additionally, good error messages are
presented in a way that is:

  • Relevant. The message presents a problem that users care about.
  • Actionable. Users should either perform an action or change their
    behavior as the result of the message.
  • User-centered. The message describes the problem in terms of target user
    actions or goals, not in terms of what
    the code is unhappy with.
  • Brief. The message is as short as possible, but no shorter.
  • Clear. The message uses plain language so that the target users can
    easily understand problem and
    solution.
  • Specific. The message describes the problem using specific language,
    giving specific names, locations, and
    values of the objects involved.
  • Courteous. Users shouldn't be blamed or made to feel stupid.
  • Rare. Displayed infrequently. Frequently displayed error messages
    are a sign of bad design.

Ruby - when I should use parenthesis or not when calling a function/method

There isn't an official standard for Ruby code best practices. However, a set of preferred styles has evolved in the Ruby community. It's a good idea to follow those preferred styles, just because it makes your code more easily readable by other Ruby programmers.

Nick Roz has given you a link to the style guide. I would also recommend that you consider installing and using rubocop. It will give you feedback on when and when not to parenthesize arguments, many other formatting matters such as proper indenting, and which of the often several different syntax options to choose in a particular situation.

To answer your specific question about whether or not to use parentheses for method arguments, the answer is yes, in general. Exceptions are, as the guide says, "methods that have 'keyword' status in Ruby." An example is puts (actually the Kernel.puts method). Most people don't use parentheses here, but the guide states that they are optional.

Another example, as Nick has said (although "methods with keyword arguments" isn't quite correct; in that case the arguments are symbols that represent methods rather than keywords), is attr_accessor, which is actually Module.attr_accessor.

So, as a general rule, if it looks like a "command" (a "keyword," if you will), but is actually a method, omit the parentheses. Otherwise, use them. And if you're not sure of the difference, get in the habit of using rubocop.

What exactly does ensure raise ActiveRecord::Rollback do?

The code in ensure is always run even if the begin section raises an unrescued exception.

begin
puts "Hello"
ensure
puts "World!"
end
max@pop-os ~/p/playground> ruby runme.rb
Hello
World!
begin
puts "Hello"
raise "Oh noes!"
ensure
puts "World!"
end
max@pop-os ~/p/playground> ruby runme.rb
Hello
World!
Traceback (most recent call last):
runme.rb:3:in `<main>': Oh noes! (RuntimeError)

Note the order here - the ensure section is executed before the execution is halted by the exception.

Thats why its used for things like closing file handlers, connections or rolling back transactions which otherwise could leave the system unstable or tie up resources.

In that particular example they are hinting on how you could preview the state change caused by an action and then undo it by always performing a rollback - even if an unexpected exception occurs.



Related Topics



Leave a reply



Submit