About Ruby exception handling

What is exception handling?

By performing exception handling, it is possible to identify the cause and location of the error and take appropriate action for the error that occurred.

In this article, we will introduce the following.

rescue Write the program you normally want to run under begin as shown below. If an exception occurs while the program is running, write the code you want to call under rescue.

begin
  p "Code to execute"
rescue
  p "Code to be executed when an exception occurs"
end

Result

"Code to execute"

else By adding else to rescue You can add the code you want to call if the exception does not occur.

begin
  p "Code to execute"
rescue
  p "Code to be executed when an exception occurs"
else
  p "Code to be executed if no exception is raised"
end

Result

"Code to execute"
"Code to be executed if no exception is raised"

Rescue usage example

If you get an exception, create a program that displays the message "An error has occurred!".

The exception is that the string is not enclosed in "" (double quotes), and the code under rescue is executed.

begin
p string
rescue
  p "Exception occured"
end

Result

"Exception occured"

ensure

By using ensure for exception handling, you can describe the processing to be executed regardless of the presence or absence of an exception.

begin
  p "Code to execute"
rescue
  p "Code to be executed when an exception occurs"
else
  p "Code to be executed if no exception is raised"
ensure
  p "Last code executed with or without exceptions"
end

Result

"Code to execute"
"Code to be executed if no exception is raised"
"Last code executed with or without exceptions"

It is used when there is a process that you want to execute reliably even if an error occurs while performing some process. (Example) In the case of a program that opens and works on a file, you can say, "Always close the file at the end regardless of the exception that occurs during execution."

Exception handling return value

--If the process ends normally without raising an exception, the last expression of begin will be the return value. --If an exception occurs, the last expression in rescue will be the return value.

(Example) When the process ends normally

class Return
  def test(n)
    begin
      1 / n
      "Begin"
    ensure
      "Ensure"
    end
  end
end

obj = Return.new
p obj.test(1)
"Begin"

(Example) When exception handling occurs

class Return
  def test(n)
    begin
      1 / n
      "Begin"
    rescue
      'Rescue'
    ensure
      "Ensure"
    end
  end
end

obj = Return.new
p obj.test(0)
"Rescue"

return If you write a return statement in ensure,

--The exception occurrence is canceled and it ends normally. --The value of ensure will be the return value of the method regardless of whether an exception has occurred.

For this reason, the originally expected processing is not executed.

Exception occurrence is canceled and ends normally

Originally, if rescue is eliminated and only ensure is described as shown below, exception handling will result in abnormal termination.

class Return
  def test(n)
    begin
      1 / n
      "Begin"
    ensure
      "Ensure"
    end
  end
end

obj = Return.new
p obj.test(1)
p obj.test(0)

Result

(ZeroDivisionError)

However, if you write a return statement in ensure, it will end normally as shown below.

class Return
  def test(n)
    begin
      1 / n
      "Begin"
    ensure
      "Ensure"
      return "return ensure"
    end
  end
end

obj = Return.new
p obj.test(1)
p obj.test(0)

Result

"return ensure"
"return ensure"

The value of ensure will be the return value of the method regardless of whether an exception has occurred.

class Return
  def test(n)
    begin
      1 / n
      "Begin"
    rescue
      'Rescue'
    ensure
      "Ensure"
      return "return ensure"
    end
  end
end

obj = Return.new
p obj.test(1) #Originally"Begin"Is returned
p obj.test(0) #Originally"Rescue"Is returned

Result

"return ensure"
"return ensure"

rescue modifier

rescue can also be used like a modifier. As shown below, if you use the rescue qualifier, you can write the process that you have to write 5 lines neatly in 1 line.

class Return
  def test
    begin
String
    rescue
      "error!!!"
    end
  end
end

obj = Return.new
p obj.test

You can write in one line with the `rescue modifier! ``

class Return
  def test
String rescue"error!!!"
  end
end

obj = Return.new
p obj.test

Result

"error!!!"

Special variables

A special variable is a variable that has a special meaning provided by ruby. Variables that assign exception objects with rescue are assigned values regardless of whether they are specified.

Special variable $!

When an exception occurs, the exception object (Exception) is assigned. If there are multiple exceptions, the last exception object will be assigned. If you don't get an exception, you'll get nil when you access it.

Special variable $ @

It will assign the backtrace where the exception occurred as an array. A backtrace follows the flow of the entire program that caused the exception and shows the information of the code that caused the exception.

[Cited references] (https://qiita.com/tsubasakat/items/6825bcefcad26da3471b)

Usage example

Even if an exception occurs in the console (irb or pry), the cause may not be known because the backtrace is not displayed. Use the special variable $ @ to display the backtrace on exceptions in the console.

irb(main):002:0> puts $@

Exception handling is provided for the entire method (begin / end omitted)

If you want to handle exceptions for the entire method, you can omit begin / end.

Example of writing begin / end


def hoge
  begin
    p 1/0
  rescue
    p "error!!!"
  end
end

Example of omitting begin / end

def hoge
  p 1/0
rescue
  p "error! !! !!"
end

raise The raise method is a method for intentionally raising an exception.

If you write as below, the raise method will raise an exception, the rescue method will be executed, and "Error !!!" will be output.

begin
  raise
  rescue
    p "error! !! !!"
end
"error! !! !!"

This method can also be used within rescue. In addition to abnormally terminating the program when an exception occurs, it can be used when you want to log exception information or send an email.

class Return
  def test(n)
    begin
      1 / n
      "Begin"
    rescue
      p "error! !! !!(log)"
      raise
    end
  end
end

obj = Return.new
obj.test(0)
"error! !! !!(log)"
Traceback (most recent call last):
        2: from ruby.rb:14:in `<main>'
        1: from ruby.rb:4:in `test'
ruby.rb:4:in `/': divided by 0 (ZeroDivisionError)

Create custom exception

Exception classes are similar to Ruby classes. Create your own exception class that inherits from StandardError.

(Example)

class Error < StandardError
end

All ruby exception objects have a message attribute. Try defining a default message for your own exception as follows:

class Error < StandardError
  def initialize(msg="Error Message")
  super
  end
end

raise Error #=> Error Message

You can add your own data to the exception.


class Error < StandardError
  attr_reader :attr

  def initialize(msg="default Error message", attr="value")
    @attr = attr
    super(msg)
  end
end

begin
  raise Error.new("Error message", "value")
rescue => e
  puts e.attr #=> value
end

You have now created your own exception.

Reference article https://qiita.com/k-penguin-sato/items/3d8ce4e71520da2d68c4

https://qiita.com/ngron/items/4c319ae7340b72c7e566

Recommended Posts

About Ruby exception handling
About exception handling
About exception handling
ruby exception handling
Ruby exception handling
[Ruby] Exception handling basics
[Java] About try-catch exception handling
[Ruby] Exception handling in functions
Exception handling
Exception handling Exception
[For Java beginners] About exception handling
Java exception handling?
About Ruby symbols
About ruby ​​form
About Ruby Hashes
About Ruby arrays
About Ruby inheritance
About ruby block
About Ruby Hashes
[Java] Exception handling
☾ Java / Exception handling
About Ruby Symbols
Java exception handling
Java exception handling
About Ruby variables
About Ruby methods
[Ruby] Exception handling, give back if given
About Ruby Kernel Module
About Ruby error messages
Exception handling practice (ArithmeticException)
About Ruby Hashes (continued)
About eval in Ruby
[ruby] About here documents
About Ruby if statement
Spring Boot exception handling
About Ruby instance methods
[Ruby] About instance generation
Ruby Learning # 28 Handling Errors
About the [ruby] operator
Thinking about logic Ruby
[Java Silver] (Exception handling) About try-catch-finally and try-with-resource statements
About the handling of Null
Classes that require exception handling
Java's first exception handling (memories)
[Java] Practice of exception handling [Exception]
Explanation about Ruby Range object
[Ruby on Rails] about has_secure_password
Java exception handling usage rules
About regular expressions in Ruby
About Ruby hashes and symbols
Ruby About various iterative processes
About Ruby and object model
About Ruby classes and instances
Exception handling techniques in Java
Explanation about Ruby String object
About the behavior of ruby Hash # ==
[In-house study session] Java exception handling (2017/04/26)
About error handling of comment function
About Ruby single quotes and double quotes
exception
About Ruby product operator (&) and sum operator (|)