Ruby Exception Handling
Exception Handling in Ruby involves how we handle the errors that come up in our program. By errors, we're not talking about syntax errors such as misspelling the Ruby keywords. We're referring to errors from which a program cannot recover, things that programmers won't anticipates but it can happen. Good programmers anticipate them and take actions to handle them.
Exception occurs due to things the system can't handle when the program is running.
Ruby: Examples of Exception
In the above program, we try to divide a number by zero. When running the program, it gives the following result :
A ZeroDivisionError
occurs because we try to divide a number by zero and that operation is not defined in Ruby.
Let's see another example:
Following is the result of the above program:
When we execute this program we get an error (No such file or directory) because the program tries to open the file which is not present in the disk. Again when we were typing the program the compiler has no way to know about the file whether such file exists or not.
In these two examples, the program terminates completely which is not what we expected. So, we have to handle the exceptions
and to prevent the program from crashing and exiting to the Operating system.
Ruby: Handling Exceptions
When we enter 0 for denominator we get the divide by zero.
We have to isolate the code that causes the exception
. So that, if an exception is raised we can transfer the control to another part of the program that handles that exception.
Here is how we do it:
The code that causes exception are written in begin
block and the rescue
block contains code that handles the exception. When the code in the begin
block raises an exception control is automatically transferred to the rescue
block and then the code inside rescue block executes and program terminates.
The exception is stored in the global variable !(exclamation mark)
. The statement print $!
prints the exception.
The output of the above program is :
When the value 0 is entered for denominator the exception
is raised and the control is transferred to the rescue
block and the statements are executed. It prints the exception and prompts to enter another value for denominator and then performs the operation and the program terminates. Here the program does not crash and does not halts completely. But this is not a perfect solution to this problem because when the user again enters the value 0 it results in exception
again which is not handled. We must use loop to handle the exception
in a perfect manner.
Ruby: Handling multiple Exceptions
When a block of code raises multiple exception
we must handle it in a different way. For example, consider the below code
The begin
block contains statements that raises "Divide by Zero" exception as well as "File not found exception". We have handled the exception only for "Divide by zero" exception.
Now, consider this code :
Here the "Divide by zero" exception is handled and there is no use for it. So, we have to be particular in handling the exception in case of multiple exceptions.
Here the exception is handled for all the types. We can handle particular exception by using the name of the exception.
We have handled ZeroDivisonError
exception by specifying its name.
We can also have multiple rescue blocks to handle each exception.
We have two rescue
blocks one to handle ZeroDivisionError
and another block for unknown exception
. There is no particular exception name for file not found exception like ZeroDivisionError
. But we can use SystemCallError
exception to handle general exception situation.
When the general exception situation happens the control transfers to the second rescue
block to handle the exception
. We can also store the exception message in the variable. Like this,
The output is :
The actual error message for the exception ZeroDivisionError
is stored in the variable zero and we print the variable.
Ruby: Raising exceptions
We can create our own exceptions in Ruby to handle errors which Ruby does not recognizes. User defined exceptions are created using raise
keyword.
The output of the program is :
Here, the first statement is executed and we have raised our exception. But the last statement is not printed because when the exception is raised, the program terminates completely.