This time I studied about exceptions again I will write it so as not to forget it. This time I will try to understand little by little, so the first time: ok_woman:
This is the process to be performed when an error occurs during code execution. There are advantages such as easier investigation of the cause.
-** begin ** Search for processing problems by specifying the code that will cause the exception.
-** rescue ** Describe the content to be dealt with when a problem occurs.
-** raise ** Describe when you want to intentionally generate an error.
-** ensure ** Execute with or without an error.
The numbers are numbered with "puts" to make the flow easier to understand.
puts 1
begin #Enclose the place where an error is likely to occur with begin
number = 0
answer = 100 / number
puts 2 #↓ If an error occurs, describe the corresponding content in rescue
rescue ZeroDivisionError => e #An object representing the exception that occurred in the e variable is assigned
p e #=> <ZeroDivisionError: divided by 0>
ensure #Execute even if an error occurs
puts 3
end
puts 4
#The movement is 1 → 3 → 4
(The variable does not have to be "e".)
If an exception occurs, the process immediately after that is not performed and the rescue process is skipped.
** Exception handler **
The part of the rescue block corresponding to the exception
The output of rescue is also as follows. (Similarly described in " p e
")
Description | Output contents |
---|---|
p "Cannot be divided by 0"(Describe the content you want to output) | "Cannot be divided by 0" |
p e.class | ZeroDivisionError |
p e.class.superclass | StandardError |
p e.message | "divided by 0" |
p e.backtrace | ["exception.rb:23:in /'", "exception.rb:23:in |
STDERR.puts "It's 0! !!" | "It's 0! !!"(Output to standard output error) |
If you write it like this, you can see various information.
Allows the caller to catch the exception.
def test_exception(number)
puts 2
begin
puts 3
answer = 100 / number #An exception occurs here! !!
return answer
puts 4
rescue ZeroDivisionError => e
puts 5
raise e
end
puts 6
end
puts 1
begin
answer = test_exception(0)
puts 7
rescue ZeroDivisionError => e
puts 8
p e #Last executed
end
#The movement is 1 → 2 → 3 → 5 → 8 →#<ZeroDivisionError: divided by 0>
The exception that occurs is automatically propagated to the caller. (Returned)
You can use raise inside the rescue block to raise it intentionally and return it to the caller who raised it.
There are many exception classes.
More details can be found here. Exception Class Reference (https://docs.ruby-lang.org/ja/latest/library/_builtin.html)
Reference: Junichi Ito. Introduction to Ruby for professionals From language specifications to test-driven development and debugging techniques
There are some things to be careful of when writing the rescue part.
begin
number = 0
answer = 100 / number
rescue Exception => e
puts "An unexpected error has occurred"
p e
rescue ZeroDivisionError => e
puts "It's 0! !!"
p e
end
#=>An unexpected error has occurred
#=> #<ZeroDivisionError: divided by 0>
Since Exception is all superclass (parent class), the second rescue is not executed, the error is caught first, and the error text of the first Exception is output.
... so when you want to output the text you want
: zap: ** Pay attention to the order of rescue! !! **: zap:
This time, I learned like this.
Next time I would like to dig a little deeper.
Recommended Posts