=pod

=for comment
DO NOT EDIT. This Pod was generated by Swim.
See http://github.com/ingydotnet/swim-pm#readme

=encoding utf8

=head1 NAME

errors - Error Handling for Perl

=for html
<a href="https://travis-ci.org/ingydotnet/error-errors-pm"><img src="https://travis-ci.org/ingydotnet/error-errors-pm.png" alt="error-errors-pm"></a>
<a href="https://coveralls.io/r/ingydotnet/error-errors-pm?branch=master"><img src="https://coveralls.io/repos/ingydotnet/error-errors-pm/badge.png" alt="error-errors-pm"></a>

=head1 STATUS

this module is still under design. Don't use it in production yet. See
L<errors::Design> for more information.

A few things in this documentation are not yet implemented.

NOTE: If you have suggestions as to how this module should behave, now is a
      great time to contact the author.

=head1 SYNOPSIS

    use strict;
    use warnings;
    use errors;

    use errors -class => 'UncoolError';

    try {
        $cool = something();
        throw UncoolError("Something is not cool")
            if not $cool;
        assert($ok, "Everything is ok");
    }
    catch UncoolError with {
        my $e = shift;
        warn "$e";
    }
    catch UserError, RuntimeError with {
        # catch UserError or RuntimeError
        # $_ is the same as $_[0]
        warn;
    }
    except {
        # $@ is the same as $_[0]
        warn "Some other error: $@";
    }
    otherwise {
        warn "No error occurred in the try clause."
    }
    finally {
        cleanup();
    };

=head1 DESCRIPTION

The C<errors> module adds clean, simple, sane, flexible and usable error
handling to Perl. The module does several things:

First, C<errors> exports an error handling syntax that is very similar to
Error.pm, but with a few improvements. (See [COMPARISON TO Error.pm])

Second, all errors that are thrown are first class Perl objects. They all
inherit from the C<Exception> class, which is provided by default. This allows
you to manipulate errors in a consistent and intuitive way.

Third, The C<errors> module makes it trivial to define your own error classes,
and encourages you to do so. Simply define a class that inherits from
C<Exception> (or one of its subclasses).

Fourth, C<errors> turns plain (string based) system errors and other die/croak
errors into specific Perl objects. It uses heuristics on the error string to
determine which Error class to use, and defaults to the C<RuntimeError> class.

Fifth, C<errors> provides dozens of predefined error classes that you can use
or that get used automatically by the auto-objectification. These classes are
in an inheritance hierarchy that should become standard for Perl.

Lastly, C<errors> is designed to play nice with the modern Perl frameworks
(like Moose) and the other popular error handling modules.

=head1 SIMPLE TO USE

The main goal of C<errors> is to encourage the widespread use of error
handling in Perl. In other languages like Python, coining your own named error
classes and using raiseI<except is as common as using if>else statements.
Here's a Python example.

    class FooError(Exception):
        pass

    try:
        something()
    except FooError as e:
        handle_error(e)

Now you can do that in Perl:

    use errors;

    package FooError;
    use base 'Exception';
    package MyModule;

    try {
        something();
    }
    catch FooError with {
        my $e = shift;
        handle_error($e);
    };

As you can see, using C<errors> is simple and unobtrusive. Why not start all
your programs with:

    use strict;
    use errors;
    use warnings;

Defining your own error classes is also trivial, and C<errors> provides an
even more concise way to do it:

    use errors -class => 'FooError';

In the catch/with clause, you can also use C<$@> (or C<$_>) to access the
current error object like this:

      catch FooError with {
          handle_error($@);
      };

=head1 USAGE

there are a few different usages of C<errors> that you should be aware of:

=over

=item C<use errors;>

This exports the C<errors> syntax, and loads all the C<errors> functionality.

=item C<< use errors -class => 'ClassName' [, -isa => 'BaseClass']; >>

The C<-class> directive gives you a way to define an error subclass at compile
time, in one simple line of code. You can optionally specify the base class.
The default base class is C<Exception>.

NOTE: This usage does not export the C<errors> (try/catch) syntax.

=item C<use errors -with_using;>

Unfortunately C<Moose> and C<errors> both export the C<with> subroutine. If
C<errors> sees that C<Moose> (or someone else) has already exported C<with>,
it will export the C<using> subroutine instead:

    use Moose;
    use errors;
    try {...} catch Exception using {...};

The C<-with_using> directive tells C<errors> to do this regardless.

=back

=head1 SYNTAX

The C<errors> module introduces a number of keyword constructs that you can
use to create and manage error objects.

=over

=item C<try { ... }>

Like an eval block. After the code is evaluated, the appropriate clauses
(catch, except, otherwise, finally) are called.

=item C<< catch <error-selector> with { ... } >>

This clause is invoked when an error happens in the C<try> block, and the
class of the error object satisfies the ErrorSelector specified. You may
specify many C<catch> clauses, to deal with different error situations.

The <error-selector> can be any of the following forms:

    # Class matches a specific error class
    catch ErrorClass with { ... }
    # Class matches a specific regexp
    catch qr/.../ with { ... }
    # A subroutine returns a true value
    catch sub { ... } with { ... }
    # One of a list of error selectors
    catch selector1, selector2, selector3 with { ... }
    # All of an array list of selectors
    catch [ selector1, selector2, selector3 ] with { ... }

=item C<except { ... }>

This clause is invoked when there is an error from the C<try> block, but no
C<catch> clauses were invoked.

=item C<otherwise { ... }>

This clause is invoked if there was no error in the C<try> clause.

=item C<finally { ... }>

This clause is always invoked as the final step in the C<try> sequence,
regardless of what happens.

=item C<throw("...");>

The throw keyword is not actually exported. It is a method call on the
Exception object. So you can use it indirectly or directly. These two calls
are identical:

    throw MyError("Something is wrong");
    MyError->throw("Something is wrong");

You can also use throw to reraise an error in a catch/except block, like this:

    $@->throw();

=item C<assert($value, "assertion message");>

This function will C<throw AssertionError($message) error unless
>$value` is true.

=back

=head1 ERROR OBJECTS

All errors are Perl objects. They all have the 'Exception' class as their
topmost parent class. They all have the following methods and properties:

=over

=item C<throw Exception($msg [, %properties]);>

This method throws a new instance of the Exception class. It is described more
fully above.

=item C<< $@->text() >>

The C<text> method gets or sets the error message for the object.

=item Stringification

All Exception objects turn into their C<text> string value when used in
string context.

=item Numification

All Exception objects turn into a unique number when used in numeric context.

=back

=head1 PREDEFINED CLASSES

The C<errors> module defines a number of error classes that it uses to cast
errors into. You can also create error objects yourself using these classes.
The classes are defined in a hierarchy:

      + Exception
        + StandardError
          + ArithmeticError
            + DivideByZeroError
          + AssertionError
          + IOError
            + IOFileError
              + IOFileOpenError
          + NotImplementedError
          + SyntaxError
          + RuntimeError
        + UserError
          + user defined errors should inherit from this

Some of these are obvious. Some deserve elaboration.

=over

=item AssertionError

Indicates a failed C<assert> call.

=item SyntaxError

Indicates a bad string eval.

=item NotImplementedError

You can throw this in a stub subroutine.

=item RuntimeError

Indicates an unknown error probably caused by a C<die> statement..

=back

NOTE: These error classes are still being determined. This list is not yet
      complete. The current hierarchy was influenced from these sources:

=over

=item * L<http://search.cpan.org/perldoc?autodie#CATEGORIES>

=item * L<http://www.python.org/dev/peps/pep-0348/#new-hierarchy>

=back

=head1 COMPARISON TO ERROR.PM

The tryI<catch>throw interface of both Errors.pm and errors.pm is very
similar. You can use both in the same runtime process (but you can only use
one or the other in the same class/package).

The C<errors> module differs from the <Error> module in the following ways:

=over

=item C<catch Selector with { ... }>

The Selector for the catch clause can only be a single class name in Error.pm.
In C<errors> it is much more flexible. See documentation for details.

=item C<except { ... }>

The except clause in Error.pm has weird semantics. In C<errors> it just gets
called if there is an error and no catch clause matches.

=item C<otherwise { ... }>

The otherwise clause in Error.pm gets called if no other handler is
appropriate. In C<errors>, it behaves like an 'else' block. It is called when
there is no error at all in the try clause.

=item Base Class

Errors in the C<Error> module have a common base class of 'Error'. In
C<errors>, the base class is called 'Exception'.

=back

=head1 FAQ

=over

=item Q: What is the difference between 'errors' and 'exceptions'?

A: Four letters.

=item Q: Is C<errors> performant?

A: Yes. Very. The module is small, simple, has no dependencies and no
   string evals.

=item Q: Why another error/exception module?

A: Because it has the perfect name.

=back

=head1 ACKNOWLEDGEMENTS

The original code and ideas for this module were taken from Error.pm.

=head1 AUTHOR

ingy döt Net <ingy@cpan.org>

=head1 COPYRIGHT

copyright 2009-2014. Ingy döt Net.

This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.

See L<http://www.perl.com/perl/misc/Artistic.html>

=cut
