D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
alt
/
ruby34
/
share
/
ri
/
system
/
Filename :
page-exceptions_md.ri
back
Copy
U:RDoc::TopLevel[ i I"exceptions.md:ETcRDoc::Parser::Markdowno:RDoc::Markup::Document:@parts[zS:RDoc::Markup::Heading: leveli: textI"Exceptions;To:RDoc::Markup::Paragraph;[I"$Ruby code can raise exceptions.;To;;[I"�Most often, a raised exception is meant to alert the running program that an unusual (i.e., _exceptional_) situation has arisen, and may need to be handled.;To;;[I"wCode throughout the Ruby core, Ruby standard library, and Ruby gems generates exceptions in certain circumstances:;To:RDoc::Markup::Verbatim;[I"OFile.open('nope.txt') # Raises Errno::ENOENT: "No such file or directory" ;T:@format:rbS; ; i;I"Raised Exceptions;To;;[I"HA raised exception transfers program execution, one way or another.;TS; ; i;I"Unrescued Exceptions;To;;[I"�If an exception not _rescued_ (see {Rescued Exceptions}[#label-Rescued+Exceptions] below), execution transfers to code in the Ruby interpreter that prints a message and exits the program (or thread):;To; ;[I"=$ ruby -e "raise" -e:1:in '<main>': unhandled exception ;T;:consoleS; ; i;I"Rescued Exceptions;To;;[I"�An <i>exception handler</i> may determine what is to happen when an exception is raised; the handler may _rescue_ an exception, and may prevent the program from exiting.;To;;[I"A simple example:;To; ;[I"�begin raise 'Boom!' # Raises an exception, transfers control. puts 'Will not get here.' rescue puts 'Rescued an exception.' # Control transferred to here; program does not exit. end puts 'Got here.' ;T;;o;;[I"Output:;To; ;[I"%Rescued an exception. Got here. ;T;0o;;[I"/An exception handler has several elements:;To:RDoc::Markup::Table:@header[I"Element;TI"Use;T:@align[00: @body[ [I"Begin clause.;TI"]Begins the handler and contains the code whose raised exception, if any, may be rescued.;T[I" One or more rescue clauses.;TI"SEach contains "rescuing" code, which is to be executed for certain exceptions.;T[I"Else clause (optional).;TI"<Contains code to be executed if no exception is raised.;T[I"Ensure clause (optional).;TI"WContains code to be executed whether or not an exception is raised, or is rescued.;T[I"<tt>end</tt> statement.;TI"Ends the handler. `;TS; ; i ;I"Begin Clause;To;;[I"3The begin clause begins the exception handler:;To:RDoc::Markup::List: @type:BULLET:@items[o:RDoc::Markup::ListItem:@label0;[o;;[I"May start with a <code>begin</code> statement; see also {Begin-Less Exception Handlers}[#label-Begin-Less+Exception+Handlers].;To;;0;[o;;[I"NContains code whose raised exception (if any) is covered by the handler.;To;;0;[o;;[I"AEnds with the first following <code>rescue</code> statement.;TS; ; i ;I"Rescue Clauses;To;;[I"A rescue clause:;To;;;;[o;;0;[o;;[I"1Starts with a <code>rescue</code> statement.;To;;0;[o;;[I"HContains code that is to be executed for certain raised exceptions.;To;;0;[o;;[I"Ends with the first following <code>rescue</code>, <code>else</code>, <code>ensure</code>, or <code>end</code> statement.;TS; ; i ;I"Rescued Exceptions;To;;[I"�A <code>rescue</code> statement may include one or more classes that are to be rescued; if none is given, StandardError is assumed.;To;;[I"�The rescue clause rescues both the specified class (or StandardError if none given) or any of its subclasses; see {Built-In Exception Class Hierarchy}[rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy].;To; ;[I"tbegin 1 / 0 # Raises ZeroDivisionError, a subclass of StandardError. rescue puts "Rescued #{$!.class}" end ;T;;o;;[I"Output:;To; ;[I"Rescued ZeroDivisionError ;T;0o;;[I"�If the <code>rescue</code> statement specifies an exception class, only that class (or one of its subclasses) is rescued; this example exits with a ZeroDivisionError, which was not rescued because it is not ArgumentError or one of its subclasses:;To; ;[I"Ibegin 1 / 0 rescue ArgumentError puts "Rescued #{$!.class}" end ;T;;o;;[I"�A <code>rescue</code> statement may specify multiple classes, which means that its code rescues an exception of any of the given classes (or their subclasses):;To; ;[I"_begin 1 / 0 rescue FloatDomainError, ZeroDivisionError puts "Rescued #{$!.class}" end ;T;;S; ; i ;I"Multiple Rescue Clauses;To;;[I"�An exception handler may contain multiple rescue clauses; in that case, the first clause that rescues the exception does so, and those before and after are ignored:;To; ;[I"�begin Dir.open('nosuch') rescue Errno::ENOTDIR puts "Rescued #{$!.class}" rescue Errno::ENOENT puts "Rescued #{$!.class}" end ;T;;o;;[I"Output:;To; ;[I"Rescued Errno::ENOENT ;T;0S; ; i ;I"%Capturing the Rescued \Exception;To;;[I"�A <code>rescue</code> statement may specify a variable whose value becomes the rescued exception (an instance of Exception or one of its subclasses:;To; ;[I"Cbegin 1 / 0 rescue => x puts x.class puts x.message end ;T;;o;;[I"Output:;To; ;[I"$ZeroDivisionError divided by 0 ;T;0S; ; i ;I"Global Variables;To;;[I"hTwo read-only global variables always have <code>nil</code> value except in a rescue clause; there:;To;;;;[o;;0;[o;;[I"5<code>$!</code>: contains the rescued exception.;To;;0;[o;;[I"-<code>$@</code>: contains its backtrace.;To;;[I" Example:;To; ;[I",begin 1 / 0 rescue p $! p $@ end ;T;;o;;[I"Output:;To; ;[I"X#<ZeroDivisionError: divided by 0> ["t.rb:2:in 'Integer#/'", "t.rb:2:in '<main>'"] ;T;0S; ; i ;I" Cause;To;;[I"�In a rescue clause, the method Exception#cause returns the previous value of <code>$!</code>, which may be <code>nil</code>; elsewhere, the method returns <code>nil</code>.;To;;[I" Example:;To; ;[I"�begin raise('Boom 0') rescue => x0 puts "Exception: #{x0.inspect}; $!: #{$!.inspect}; cause: #{x0.cause.inspect}." begin raise('Boom 1') rescue => x1 puts "Exception: #{x1.inspect}; $!: #{$!.inspect}; cause: #{x1.cause.inspect}." begin raise('Boom 2') rescue => x2 puts "Exception: #{x2.inspect}; $!: #{$!.inspect}; cause: #{x2.cause.inspect}." end end end ;T;;o;;[I"Output:;To; ;[I"Exception: #<RuntimeError: Boom 0>; $!: #<RuntimeError: Boom 0>; cause: nil. Exception: #<RuntimeError: Boom 1>; $!: #<RuntimeError: Boom 1>; cause: #<RuntimeError: Boom 0>. Exception: #<RuntimeError: Boom 2>; $!: #<RuntimeError: Boom 2>; cause: #<RuntimeError: Boom 1>. ;T;0S; ; i ;I"Else Clause;To;;[I""The <code>else</code> clause:;To;;;;[o;;0;[o;;[I"0Starts with an <code>else</code> statement.;To;;0;[o;;[I"XContains code that is to be executed if no exception is raised in the begin clause.;To;;0;[o;;[I"UEnds with the first following <code>ensure</code> or <code>end</code> statement.;To; ;[I"hbegin puts 'Begin.' rescue puts 'Rescued an exception!' else puts 'No exception raised.' end ;T;;o;;[I"Output:;To; ;[I"!Begin. No exception raised. ;T;0S; ; i ;I"Ensure Clause;To;;[I"The ensure clause:;To;;;;[o;;0;[o;;[I"2Starts with an <code>ensure</code> statement.;To;;0;[o;;[I"�Contains code that is to be executed regardless of whether an exception is raised, and regardless of whether a raised exception is handled.;To;;0;[o;;[I">Ends with the first following <code>end</code> statement.;To; ;[I"�def foo(boom: false) puts 'Begin.' raise 'Boom!' if boom rescue puts 'Rescued an exception!' else puts 'No exception raised.' ensure puts 'Always do this.' end foo(boom: true) foo(boom: false) ;T;;o;;[I"Output:;To; ;[I"^Begin. Rescued an exception! Always do this. Begin. No exception raised. Always do this. ;T;0S; ; i ;I"End Statement;To;;[I"5The <code>end</code> statement ends the handler.;To;;[I"JCode following it is reached only if any raised exception is rescued.;TS; ; i ;I"#Begin-Less \Exception Handlers;To;;[I"iAs seen above, an exception handler may be implemented with <code>begin</code> and <code>end</code>.;To;;[I"5An exception handler may also be implemented as:;To;;;;[o;;0;[o;;[I"A method body:;Fo; ;[I"�def foo(boom: false) # Serves as beginning of exception handler. puts 'Begin.' raise 'Boom!' if boom rescue puts 'Rescued an exception!' else puts 'No exception raised.' end # Serves as end of exception handler. ;F;;o;;0;[o;;[I" A block:;Fo; ;[I"�Dir.chdir('.') do |dir| # Serves as beginning of exception handler. raise 'Boom!' rescue puts 'Rescued an exception!' end # Serves as end of exception handler. ;F;;S; ; i ;I"Re-Raising an \Exception;To;;[I"�It can be useful to rescue an exception, but allow its eventual effect; for example, a program can rescue an exception, log data about it, and then "reinstate" the exception.;To;;[I"aThis may be done via the <code>raise</code> method, but in a special way; a rescuing clause:;To;;;;[o;;0;[o;;[I"Captures an exception.;To;;0;[o;;[I"KDoes whatever is needed concerning the exception (such as logging it).;To;;0;[o;;[I"ZCalls method <code>raise</code> with no argument, which raises the rescued exception:;To; ;[I"�begin 1 / 0 rescue ZeroDivisionError # Do needful things (like logging). raise # Raised exception will be ZeroDivisionError, not RuntimeError. end ;T;;o;;[I"Output:;To; ;[I"cruby t.rb t.rb:2:in 'Integer#/': divided by 0 (ZeroDivisionError) from t.rb:2:in '<main>' ;T;0S; ; i ;I" Retrying;To;;[I"�It can be useful to retry a begin clause; for example, if it must access a possibly-volatile resource (such as a web page), it can be useful to try the access more than once (in the hope that it may become available):;To; ;[I"�retries = 0 begin puts "Try ##{retries}." raise 'Boom' rescue puts "Rescued retry ##{retries}." if (retries += 1) < 3 puts 'Retrying' retry else puts 'Giving up.' raise end end ;T;;o; ;[I"�Try #0. Rescued retry #0. Retrying Try #1. Rescued retry #1. Retrying Try #2. Rescued retry #2. Giving up. # RuntimeError ('Boom') raised. ;T;0o;;[I"kNote that the retry re-executes the entire begin clause, not just the part after the point of failure.;TS; ; i;I"Raising an \Exception;To;;[I".\Method Kernel#raise raises an exception.;TS; ; i;I"Custom Exceptions;To;;[I"&To provide additional or alternate information, you may create custom exception classes. Each should be a subclass of one of the built-in exception classes (commonly StandardError or RuntimeError); see {Built-In Exception Class Hierarchy}[rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy].;To; ;[I",class MyException < StandardError; end ;T;;S; ; i;I" Messages;To;;[I"�Every <code>Exception</code> object has a message, which is a string that is set at the time the object is created; see Exception.new.;To;;[I"zThe message cannot be changed, but you can create a similar object with a different message; see Exception#exception.;To;;[I"0This method returns the message as defined:;To;;;;[o;;0;[o;;[I"Exception#message.;To;;[I"?Two other methods return enhanced versions of the message:;To;;;;[o;;0;[o;;[I"WException#detailed_message: adds exception class name, with optional highlighting.;To;;0;[o;;[I"aException#full_message: adds exception class name and backtrace, with optional highlighting.;To;;[I" Each of the two methods above accepts keyword argument <code>highlight</code>; if the value of keyword <code>highlight</code> is <code>true</code>, the returned string includes bolding and underlining ANSI codes (see below) to enhance the appearance of the message.;To;;[I"6Any exception class (Ruby or custom) may choose to override either of these methods, and may choose to interpret keyword argument <tt>highlight: true</tt> to mean that the returned message should contain {ANSI codes}[https://en.wikipedia.org/wiki/ANSI_escape_code] that specify color, bolding, and underlining.;To;;[I"�Because the enhanced message may be written to a non-terminal device (e.g., into an HTML page), it is best to limit the ANSI codes to these widely-supported codes:;To;;;;[o;;0;[o;;[I"Begin font color:;Fo;;[I" Color;FI"ANSI Code;F;[00;[[I"Red;FI"<tt>\e[31m</tt>;F[I" Green;FI"<tt>\e[32m</tt>;F[I"Yellow;FI"<tt>\e[33m</tt>;F[I" Blue;FI"<tt>\e[34m</tt>;F[I"Magenta;FI"<tt>\e[35m</tt>;F[I" Cyan;FI"<tt>\e[36m</tt>;Fo;;[I" <br>;To;;;;[o;;0;[o;;[I"Begin font attribute:;Fo;;[I"Attribute;FI"ANSI Code;F;[00;[[I" Bold;FI"<tt>\e[1m</tt>;F[I"Underline;FI"<tt>\e[4m</tt>;Fo;;[I" <br>;To;;;;[o;;0;[o;;[I"End all of the above:;Fo;;[I" Color;FI"ANSI Code;F;[00;[[I" Reset;FI"<tt>\e[0m</tt>;Fo;;[I"�It's also best to craft a message that is conveniently human-readable, even if the ANSI codes are included "as-is" (rather than interpreted as font directives).;TS; ; i;I"Backtraces;To;;[I"�A _backtrace_ is a record of the methods currently in the {call stack}[https://en.wikipedia.org/wiki/Call_stack]; each such method has been called, but has not yet returned.;To;;[I"0These methods return backtrace information:;To;;;;[o;;0;[o;;[I"[Exception#backtrace: returns the backtrace as an array of strings or <code>nil</code>.;To;;0;[o;;[I"�Exception#backtrace_locations: returns the backtrace as an array of Thread::Backtrace::Location objects or <code>nil</code>. Each Thread::Backtrace::Location object gives detailed information about a called method.;To;;[I"^By default, Ruby sets the backtrace of the exception to the location where it was raised.;To;;[I"{The developer might adjust this by either providing +backtrace+ argument to Kernel#raise, or using Exception#set_backtrace.;To;;[I"Note that:;To;;;;[o;;0;[o;;[I"Yby default, both +backtrace+ and +backtrace_locations+ represent the same backtrace;;To;;0;[o;;[I"�if the developer sets the backtrace by one of the above methods to an array of Thread::Backtrace::Location, they still represent the same backtrace;;To;;0;[o;;[I"Lif the developer sets the backtrace to a string or an array of strings:;To;;0;[o;;[I"9by Kernel#raise: +backtrace_locations+ become +nil+;;To;;0;[o;;[I"Sby Exception#set_backtrace: +backtrace_locations+ preserve the original value;;To;;0;[o;;[I"�if the developer sets the backtrace to +nil+ by Exception#set_backtrace, +backtrace_locations+ preserve the original value; but if the exception is then reraised, both +backtrace+ and +backtrace_locations+ become the location of reraise.;T: @file@:0@omit_headings_from_table_of_contents_below0