Exceptions

Exceptions

  • Don’t use exceptions for flow of control.
    [link]
  # bad
  begin
    n / d
  rescue ZeroDivisionError
    puts "Cannot divide by 0!"
  end

  # good
  if d.zero?
    puts "Cannot divide by 0!"
  else
    n / d
  end
  • Avoid rescuing the Exception class.
    [link]
  # bad
  begin
    # an exception occurs here
  rescue Exception
    # exception handling
  end

  # good
  begin
    # an exception occurs here
  rescue StandardError
    # exception handling
  end

  # acceptable
  begin
    # an exception occurs here
  rescue
    # exception handling
  end
  • Don’t specify RuntimeError explicitly in
    the two argument version of raise. Prefer error sub-classes for clarity and
    explicit error creation.[link]
  # bad
  raise RuntimeError, 'message'

  # better - RuntimeError is implicit here
  raise 'message'

  # best
  class MyExplicitError < RuntimeError; end
  raise MyExplicitError
  • Prefer supplying an exception class and a message as two separate arguments
    to raise, instead of an exception instance.
    [link]
  # bad
  raise SomeException.new('message')
  # Note that there is no way to do `raise SomeException.new('message'), backtrace`.

  # good
  raise SomeException, 'message'
  # Consistent with `raise SomeException, 'message', backtrace`.
  • Avoid using rescue in its modifier form.
    [link]
  # bad
  read_file rescue handle_error($!)

  # good
  begin
    read_file
  rescue Errno:ENOENT => ex
    handle_error(ex)
  end