Ruby Exceptions
Exceptions and execution are always linked. If you open a file that does not exist and do not handle this situation properly, your program is considered low quality.
If an exception occurs, the program stops. Exceptions are used to handle various types of errors that may occur during program execution, so appropriate action can be taken without letting the program stop completely.
Ruby provides a perfect mechanism for handling exceptions. We canbegin/endattach code that may raise an exception in a block, and userescueclause to tell Ruby exactly which exception types to handle.
Syntax
frombegintorescueEverything inside is protected. If an exception occurs during execution of the block, control is passed torescueandendthe block between.
Forbegineach in the blockrescueclause, Ruby compares the raised exception with each parameter in turn. If the exception named in a rescue clause is the same type as the currently raised exception, or is a parent class of that exception, then the match succeeds.
If the exception does not match all specified error types, we can at all therescueafter the clauses use aelseclause.
Examples
The above example outputs the result. You can see,STDINreplacedfile, becauseopeningfailed.
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
UsingretryStatement
You can userescuea block to catch exceptions, then useretrystatement to execute from the beginningbeginblock.
Syntax
Examples
The following is the processing flow:
- An exception occurs when opening.
- Jump to rescue. fname is reassigned.
- Jump to the beginning of begin via retry.
- This time the file opens successfully.
- Continue with the basic process.
Note:If the renamed file does not exist, this example code will try infinitely. So when handling exceptions, use with cautionretry。
UsingraiseStatement
You can useraisestatement to raise an exception. The following method raises an exception when called. Its second message will be output.
Syntax
The first form simply re-raises the current exception (or raises a RuntimeError if there is no current exception). This is used in exception handlers that need to explain the exception before passing it on.
The second form creates a newRuntimeErrorexception, setting its message to the given string. The exception is then thrown to the call stack.
The third form creates an exception using the first parameter, then sets the associated message to the second parameter.
The fourth form is similar to the third form, and you can add any additional conditional statements (such asunless) to raise the exception.
Examples
The above example outputs:
I am before the raise. I am rescued. I am after the begin block.
Another demonstrationraiseexample of usage:
Examples
The above example outputs:
A test exception. ["main.rb:4"]
UsingensureStatement
Sometimes, whether or not an exception is raised, you need to ensure that some processing is completed when the code block ends. For example, you may have opened a file on entry, and when you exit the block, you need to make sure the file is closed.
ensureThe ensure clause does exactly this. ensure is placed after the last rescue clause and contains a block of code that is always executed when the block terminates. It does not matter whether the block exits normally, whether it raises and handles an exception, or whether it terminates due to an uncaught exception,ensurethe block will always run.
Syntax
Examples
The above example outputs:
A test exception. ["main.rb:4"] Ensuring execution
UsingelseStatement
If aelseclause is provided, it is generally placed after therescueclause, before anyensurebefore.
elseThe body of the clause is executed only when the main body of the code does not raise an exception.
Syntax
Examples
The above example outputs:
I'm not raising exception Congratulations-- no errors! Ensuring execution
Using the $! variable, you can capture the raised error message.
Catch and Throw
The exception mechanism of raise and rescue can abandon execution when an error occurs. Sometimes you need to jump out of some deeply nested structures during normal processing. This is where catch and throw come in handy.
catchdefines a block that uses the given name (which can be a Symbol or String) as a label. The block executes normally until it encounters a throw.
Syntax
Examples
In the following example, if the user types '!' in response to any prompt, a throw is used to terminate interaction with the user.
Examples
The above program requires human interaction; you can try it on your computer. The above example outputs:
Name: Ruby on Rails Age: 3 Sex: ! Name:Just Ruby
Class Exception
Ruby's standard classes and modules raise exceptions. All exception classes form a hierarchy, including the Exception class at the top. The next level down consists of seven different types:
- Interrupt
- NoMemoryError
- SignalException
- ScriptError
- StandardError
- SystemExit
Fatal is another exception in this level, but the Ruby interpreter uses it only internally.
Both ScriptError and StandardError have some subclasses, but we do not need to understand those details here. The most important thing is to create our own exception classes, which must be subclasses of the Exception class or its descendants.
Let's look at an example:
Examples
Now, look at the following example, which will use the above exception:
Examples
Here, the most important line is raiseFileSaveError.new($!). We call raise to signal that an exception has occurred, passing a new instance of FileSaveError because the specific exception caused the data write to fail.
Other extensions