txt: ## exceptions.md
  Exceptions
  
  Using exceptions in Raku
  
  Exceptions in Raku are objects that hold information about errors. An error can be, for example, the unexpected receiving of data or a network connection no longer available, or a missing file. The information that an exception object stores is, for instance, a human-readable message about the error condition, the backtrace of the raising of the error, and so on.
  
  All built-in exceptions inherit from [`Exception`](/type/Exception), which provides some basic behavior, including the storage of a backtrace and an interface for the backtrace printer.
  
  # [*Ad hoc* exceptions](#Exceptions "go to top of document")[§](#Ad_hoc_exceptions "direct link")
  
  Ad hoc exceptions can be used by calling [die](/routine/die) with a description of the error:
  
  ```raku
  die "oops, something went wrong";
  # OUTPUT: «oops, something went wrong in block <unit> at my-script.raku:1␤»
  ```
  
  It is worth noting that `die` prints the error message to the standard error `$*ERR`.
  
  # [Typed exceptions](#Exceptions "go to top of document")[§](#Typed_exceptions "direct link")
  
  Typed exceptions provide more information about the error stored within an exception object.
  
  For example, if while executing `.frobnicate` on an object, a needed path `foo/bar` becomes unavailable, then an [`X::IO::DoesNotExist`](/type/X/IO/DoesNotExist) exception can be thrown:
  
  ```raku
  method frobnicate($path) {
      X::IO::DoesNotExist.new(:$path, :trying("frobnicate")).throw
        unless $path.IO.e;
      # do the actual frobnication
  }
  
  ```
  
  ```raku
  frobnicate("foo/bar");
  # OUTPUT: «Failed to find 'foo/bar' while trying to do '.frobnicate'
  #          in block <unit> at my-script.raku:1»
  
  ```
  
  Note how the object has provided the backtrace with information about what went wrong. A user of the code can now more easily find and correct the problem.
  
  Instead of calling the `.throw` method on the [`X::IO::DoesNotExist`](/type/X/IO/DoesNotExist) object, one can also use that object as a parameter to `die`:
  
  ```raku
  die X::IO::DoesNotExist.new(:$path, :trying("frobnicate"));
  
  ```
  
  # [Catching exceptions](#Exceptions "go to top of document")[§](#Catching_exceptions "direct link")
  
  It's possible to handle exceptional circumstances by supplying a `CATCH` block:
  
  ```raku
  CATCH {
      when X::IO { $*ERR.say: "some kind of IO exception was caught!" }
  }
  X::IO::DoesNotExist.new(:$path, :trying("frobnicate")).throw
  
  # OUTPUT: «some kind of IO exception was caught!»
  
  ```
  
  Here, we are saying that if any exception of type [`X::IO`](/type/X/IO) occurs, then the message `some kind of IO exception was caught!` will be sent to *stderr*, which is what `$*ERR.say` does, getting displayed on whatever constitutes the standard error device in that moment, which will probably be the console by default.
  
  A `CATCH` block uses smartmatching similar to how `given/when` smartmatches on options, thus it's possible to catch and handle various categories of exceptions inside a `when` block. And it does so because, within the block, `$_` is set to the exception that has been raised.
  
  To handle all exceptions, use a `default` statement. This example prints out almost the same information as the normal backtrace printer; the *dot* methods apply to `$_`, which holds the [`Exception`](/type/Exception) within the `CATCH` block.
  
  ```raku
  CATCH {
       default {
           $*ERR.say: .message;
           for .backtrace.reverse {
               next if .file.starts-with('SETTING::');
               next unless .subname;
               $*ERR.say: "  in block {.subname} at {.file} line {.line}";
           }
       }
  }
  ```
  
  Note that the match target is a role. To allow user defined exceptions to match in the same manner, they must implement the given role. Just existing in the same namespace will look alike but won't match in a `CATCH` block.
  
  Note that the `CATCH` block semantics apply to the **entire** lexical scope in which it is defined, **regardless** of where it is defined inside that lexical scope. It is therefore advised to put any `CATCH` block at the start of the lexical scope to which they apply so that the casual reader of the code can immediately see that there is something special going on.
  
  ## [Exception handlers and enclosing blocks](#Exceptions "go to top of document")[§](#Exception_handlers_and_enclosing_blocks "direct link")
  
  After a CATCH has handled the exception, the block enclosing the `CATCH` block is exited.
  
  In other words, even when the exception is handled successfully, the *rest of the code* in the enclosing block will never be executed.
  
  ```raku
  die "something went wrong ...";
  
  CATCH {
      # will definitely catch all the exception
      default { .Str.say; }
  }
  
  say "This won't be said.";   # but this line will be never reached since
                               # the enclosing block will be exited immediately
  # OUTPUT: «something went wrong ...␤»
  ```
  
  Compare with this:
  
  ```raku
  CATCH {
  
    CATCH {
        default { .Str.say; }
    }
  
    die "something went wrong ...";
  
  }
  
  say "Hi! I am at the outer block!"; # OUTPUT: «Hi! I am at the outer block!␤»
  ```
  
  See [Resuming of exceptions](/language/exceptions#Resuming_of_exceptions), for how to return control back to where the exception originated.
  
  # [`try` blocks](#Exceptions "go to top of document")[§](#try_blocks "direct link")
  
  A `try` block is a normal block which implicitly turns on the [`use fatal` pragma](/language/pragmas#fatal) and includes an implicit `CATCH` block that drops the exception, which means you can use it to contain them. Caught exceptions are stored inside the `$!` variable, which holds a value of type [`Exception`](/type/Exception).
  
  A normal block like this one will simply fail:
  
  ```raku
  {
      my $x = +"a";
      say $x.^name;
  } # OUTPUT: «Failure␤»
  
  ```
  
  However, a `try` block will contain the exception and put it into the `$!` variable:
  
  ```raku
  try {
      my $x = +"a";
      say $x.^name;
  }
  
  if $! { say "Something failed!" } # OUTPUT: «Something failed!␤»
  say $!.^name;                     # OUTPUT: «X::Str::Numeric␤»
  
  ```
  
  Any exception that is thrown in such a block will be caught by a `CATCH` block, either implicit or provided by the user. In the latter case, any unhandled exception will be rethrown. If you choose not to handle the exception, they will be contained by the block.
  
  ```raku
  try {
      die "Tough luck";
      say "Not gonna happen";
  }
  
  try {
      fail "FUBAR";
  }
  
  ```
  
  In both `try` blocks above, exceptions will be contained within the block, but the `say` statement will not be run. We can handle them, though:
  
  ```raku
  class E is Exception { method message() { "Just stop already!" } }
  
  try {
      E.new.throw; # this will be local
  
      say "This won't be said.";
  }
  
  say "I'm alive!";
  
  try {
      CATCH {
          when X::AdHoc { .Str.say; .resume }
      }
  
      die "No, I expect you to DIE Mr. Bond!";
  
      say "I'm immortal.";
  
      E.new.throw;
  
      say "No, you don't!";
  }
  ```
  
  Which would output:
  
  ｢text｣ without highlighting
  
  ```
  
  
  ```
  
  I'm alive!
  No, I expect you to DIE Mr. Bond!
  I'm immortal.
  Just stop already!
    in block <unit> at exception.raku line 21
  
  
  ```
  
  
  ```
  
  Since the `CATCH` block is handling just the [`X::AdHoc`](/type/X/AdHoc) exception thrown by the `die` statement, but not the `E` exception. In the absence of a `CATCH` block, all exceptions will be contained and dropped, as indicated above. `resume` will resume execution right after the exception has been thrown; in this case, in the `die` statement. Please consult the section on [resuming of exceptions](/language/exceptions#Resuming_of_exceptions) for more information on this.
  
  A `try`-block is a normal block and as such treats its last statement as the return value of itself. We can therefore use it as a right-hand side.
  
  ```raku
  say try { +"99999" } // "oh no"; # OUTPUT: «99999␤»
  say try { +"hello" } // "oh no"; # OUTPUT: «oh no␤»
  
  ```
  
  Try blocks support `else` blocks indirectly by returning the return value of the expression or [`Nil`](/type/Nil) if an exception was thrown.
  
  ```raku
  with try +"♥" {
      say "this is my number: $_"
  } else {
      say "not my number!"
  }
  # OUTPUT: «not my number!␤»
  ```
  
  `try` can also be used with a statement instead of a block, that is, as a [statement prefix](/language/statement-prefixes#try):
  
  ```raku
  say try "some-filename.txt".IO.slurp // "sane default";
  # OUTPUT: «sane default␤»
  
  ```
  
  What `try` actually causes is, via the `use fatal` pragma, an immediate throw of the exceptions that happen within its scope, but by doing so the `CATCH` block is invoked from the point where the exception is thrown, which defines its scope.
  
  ```raku
  my $error-code = "333";
  sub bad-sub {
      die "Something bad happened";
  }
  try {
      my $error-code = "111";
      bad-sub;
  
      CATCH {
          default {
              say "Error $error-code ", .^name, ': ',.Str
          }
      }
  }
  # OUTPUT: «Error 111 X::AdHoc: Something bad happened␤»
  
  ```
  
  # [Throwing exceptions](#Exceptions "go to top of document")[§](#Throwing_exceptions "direct link")
  
  Exceptions can be thrown explicitly with the `.throw` method of an [`Exception`](/type/Exception) object.
  
  This example throws an [`X::AdHoc`](/type/X/AdHoc) exception, catches it and allows the code to continue from the point of the exception by calling the `.resume` method.
  
  ```raku
  {
      X::AdHoc.new(:payload<foo>).throw;
      "OHAI".say;
      CATCH {
          when X::AdHoc { .resume }
      }
  }
  
  "OBAI".say;
  
  # OUTPUT: «OHAI␤OBAI␤»
  ```
  
  If the `CATCH` block doesn't match the exception thrown, then the exception's payload is passed on to the backtrace printing mechanism.
  
  ```raku
  {
      X::AdHoc.new(:payload<foo>).throw;
      "OHAI".say;
      CATCH {  }
  }
  
  "OBAI".say;
  
  # OUTPUT: «foo
  #          in block <unit> at my-script.raku:1»
  ```
  
  This next example doesn't resume from the point of the exception. Instead, it continues after the enclosing block, since the exception is caught, and then control continues after the `CATCH` block.
  
  ```raku
  {
      X::AdHoc.new(:payload<foo>).throw;
      "OHAI".say;
      CATCH {
          when X::AdHoc { }
      }
  }
  
  "OBAI".say;
  
  # OUTPUT: «OBAI␤»
  ```
  
  `throw` can be viewed as the method form of `die`, just that in this particular case, the sub and method forms of the routine have different names.
  
  # [Resuming of exceptions](#Exceptions "go to top of document")[§](#Resuming_of_exceptions "direct link")
  
  Exceptions interrupt control flow and divert it away from the statement following the statement that threw it. Any exception handled by the user can be resumed and control flow will continue with the statement following the statement that threw the exception. To do so, call the method `.resume` on the exception object.
  
  ```raku
  CATCH { when X::AdHoc { .resume } }         # this is step 2
  
  die "We leave control after this.";         # this is step 1
  
  say "We have continued with control flow."; # this is step 3
  ```
  
  Resuming will occur right after the statement that has caused the exception, and in the innermost call frame:
  
  ```raku
  sub bad-sub {
      die "Something bad happened";
      return "not returning";
  }
  
  {
      my $return = bad-sub;
      say "Returned $return";
      CATCH {
          default {
              say "Error ", .^name, ': ',.Str;
              $return = '0';
              .resume;
  
          }
      }
  }
  # OUTPUT:
  # Error X::AdHoc: Something bad happened
  # Returned not returning
  
  ```
  
  In this case, `.resume` is getting to the `return` statement that happens right after the `die` statement. Please note that the assignment to `$return` is taking no effect, since the `CATCH` statement is happening *inside* the call to `bad-sub`, which, via the `return` statement, assigns the `not returning` value to it.
  
  # [Uncaught exceptions](#Exceptions "go to top of document")[§](#Uncaught_exceptions "direct link")
  
  If an exception is thrown and not caught, it causes the program to exit with a non-zero status code, and typically prints a message to the standard error stream of the program. This message is obtained by calling the `gist` method on the exception object. You can use this to suppress the default behavior of printing a backtrace along with the message:
  
  ```raku
  class X::WithoutLineNumber is X::AdHoc {
      multi method gist(X::WithoutLineNumber:D:) {
          $.payload
      }
  }
  die X::WithoutLineNumber.new(payload => "message")
  
  # prints "message\n" to $*ERR and exits, no backtrace
  ```
  
  # [Control exceptions](#Exceptions "go to top of document")[§](#Control_exceptions "direct link")
  
  Control exceptions are raised when throwing an Exception which does the [`X::Control`](/type/X/Control) role (since Rakudo 2019.03). They are usually thrown by certain [keywords](/language/phasers#CONTROL) and are handled either automatically or by the appropriate [phaser](/language/phasers#Loop_phasers). Any unhandled control exception is converted to a normal exception.
  
  ```raku
  { return; CATCH { default { $*ERR.say: .^name, ': ', .Str } } }
  # OUTPUT: «X::ControlFlow::Return: Attempt to return outside of any Routine␤»
  # was CX::Return
  
  ```
  