ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ???????????????????????????????????? ???????????????????????????????????? ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ???????????????????????????????????? ???????????????????????????????????? U:RDoc::TopLevel[ iI"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 '
': unhandled exception ;T;: consoleS; ; i; I"Rescued Exceptions;To; ;[I"An exception handler 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"end 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 begin 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 rescue statement.;TS; ; i ; I"Rescue Clauses;To; ;[I"A rescue clause:;To;;;;[o;;0;[o; ;[I"1Starts with a rescue 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 rescue, else, ensure, or end statement.;TS; ; i ; I"Rescued Exceptions;To; ;[I"A rescue 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 rescue 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 rescue 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 rescue 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 nil value except in a rescue clause; there:;To;;;;[o;;0;[o; ;[I"5$!: contains the rescued exception.;To;;0;[o; ;[I"-$@: contains its backtrace.;To; ;[I" Example:;To; ;[I",begin 1 / 0 rescue p $! p $@ end ;T;;o; ;[I" Output:;To; ;[I"X# ["t.rb:2:in 'Integer#/'", "t.rb:2:in '
'"] ;T;0S; ; i ; I" Cause;To; ;[I"In a rescue clause, the method Exception#cause returns the previous value of $!, which may be nil; elsewhere, the method returns nil.;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: #; $!: #; cause: nil. Exception: #; $!: #; cause: #. Exception: #; $!: #; cause: #. ;T;0S; ; i ; I"Else Clause;To; ;[I""The else clause:;To;;;;[o;;0;[o; ;[I"0Starts with an else 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 ensure or end 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 ensure 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 end 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 end 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 begin and end.;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 raise 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 raise 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 '
' ;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 Exception 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 highlight; if the value of keyword highlight is true, 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 highlight: true 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"\e[31m;F[I" Green;FI"\e[32m;F[I" Yellow;FI"\e[33m;F[I" Blue;FI"\e[34m;F[I" Magenta;FI"\e[35m;F[I" Cyan;FI"\e[36m;Fo; ;[I"
;To;;;;[o;;0;[o; ;[I"Begin font attribute:;Fo;;[I"Attribute;FI"ANSI Code;F;[00;[[I" Bold;FI"\e[1m;F[I"Underline;FI"\e[4m;Fo; ;[I"
;To;;;;[o;;0;[o; ;[I"End all of the above:;Fo;;[I" Color;FI"ANSI Code;F;[00;[[I" Reset;FI"\e[0m;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 nil.;To;;0;[o; ;[I"Exception#backtrace_locations: returns the backtrace as an array of Thread::Backtrace::Location objects or nil. 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