Ruby exception is an object, an instance of the class Exception or descendent of that class. It represents some exceptional condition.
In a Ruby program, when something goes wrong, it throws an exceptional behavior. By default Ruby program terminates on throwing an exception.
We can declare some exception handlers within Ruby. An exception handler is a block of code which is executed when exception occurs in some other block of code.
Exceptions are handled in two ways. Either you can terminate the program or deal with the exception. To deal with an exception, you can provide a rescue clause. By providing this, program control flows to the rescue clause.
When an exception is raised but not handled, global variable $! contains the current exception and $@ contains the current exception's backtrace.
Ruby predefined classes like Exception and its children helps you to handle errors of your program. In Ruby exception hierarchy, most of the sub classes extend class StandardError. These are the normal exceptions.
Ruby Class Exceptions
Built-in subclasses of exception are as follows:
The raise method comes from the Kernel module.
Handling an Exception
To handle exception, the code that raises exception is enclosed within begin-end block. Using rescue clauses we can state type of exceptions we want to handle.
In the above example, interrupted code does not run completely. After exception handling code resumes after the begin-end block.
If no argument is defined in the rescue clause, the parameter defaults to StandardError. Each rescue clause specify multiple exceptions to catch. If raise is used without any parameters, exception may re-raised.
The rescue clauses are written in a begin/rescue block. Exceptions if not handled by one rescue clause will br handled with the next one.
In the begin block, each rescue clause with the raised exception will be compared against each of parameters in turn. It will be matched when the type of error thrown and exception named in the rescue clause is either same or is a superclass of that exception. The else clause is executed if body of begin statement is completed without exceptions. If an exception occurs, else clause will not be executed.
Exception objects are normal objects. A rescued exception can be hold to a variable within the rescue clause.
The Exception class defines two methods that return details about the exception. The message method returns a string that define the explanation of error. The backtrace method returns an array of string that represent the call stack at that point where exception was raised.
Using retry Statement
Usaually in a rescue clause, the exception is captured and code resumes after begin block. Using retry statement, the rescue block code can be resumed from begin after capturing an exception.
The above program runs as follows:
Step 1 In the begin block, code is written to make a directory that already exists.
Step 2 This will throw an error.
Step 3 In rescue block, y was reassigned.
Step 4 The retry statement will go to the begin block.
Step 5 Directory will be created.
Using raise Statement
The raise statement is used to raise an exception.
The first one re-raises the current exception. It is used for exception handlers where exception is intercepted before passing it on.
The second one creates a new RuntimeError exception. This exception is then raised up the call stack.
The third one uses first argument to create an exception, then sets associated message to the second argument.
The fourth one similar to third one. In this you can add any conditional statement to raise an exception.
Using ensure Statement
There is an ensure clause which guarantees some processing at the end of code. The ensure block always run whether an exception is raised or not. It is placed after last rescue clause and will always executed as the block terminates.
The ensure block will run at any case whether an exception arises, exception is rescued or code is terminated by uncaught exception.
Using else Statement
The else clause is always present after rescue clause and before ensure clause. If no exceptions are raised, then only else block is executed.
Ruby Catch and Throw
Ruby catch and throw provide a way to jump from the execution early when no further work is needed in a code.
The catch defines a block that is labeled with a given name. It is used to jump out of nested code. Using catch, the block will be executed normally until throw is encountered.
The catch and throw method is faster than rescue and raise clauses. Hence, it is more suitable to use.