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.
In the above program, we try to divide a number by zero. When running the program, it gives the following result :
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.
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.
When a block of code raises
multiple exception we must handle it in a different way. For example, consider the below code
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.
We can create our own exceptions in Ruby to handle errors which Ruby does not recognizes. User defined exceptions are created using
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.