NAME

Throwable::Factory - lightweight Moo-based exception class factory

SYNOPSIS

use Throwable::Factory
   GeneralException => undef,
   FileException    => [qw( $filename )],
   NetworkException => [qw( $remote_addr $remote_port )],
;

# Just a message...
#
GeneralException->throw("Something bad happened");

# Or use named parameters...
#
GeneralException->throw(message => "Something awful happened");

# The message can be a positional parameter, even while the
# rest are named.
#
FileException->throw(
   "Can't open file",
   filename => '/tmp/does-not-exist.txt',
);

# Or, they all can be a positional using an arrayref...
#
NetworkException->throw(["Timed out", "11.22.33.44", 555]);

DESCRIPTION

Throwable::Factory is an Exception::Class-like exception factory using MooX::Struct.

All exception classes built using Throwable::Factory are MooX::Struct structs, but will automatically include a message attribute, will compose the Throwable and StackTrace::Auto roles, and contain the following convenience methods:

error

Read-only alias for the message attribute/field.

package

Get the package for the first frame on the stack trace.

file

Get the file name for the first frame on the stack trace.

line

Get the line number for the first frame on the stack trace.

They provide a BUILDARGS method which means that if their constructor is called with an odd number of arguments, the first is taken to be the message, and the rest named parameters.

Additionally, the factory can be called with Exception::Class-like hashrefs to describe the exception classes. The following two definitions are equivalent:

# MooX::Struct-style
use Throwable::Factory FooBar => [
   -extends => ['Foo'],
   qw( foo bar ),
];

# Exception::Class-style
use Throwable::Factory FooBar => {
   isa    => 'Foo',
   fields => [qw( foo bar )],
};

Exception Taxonomy

It can be useful to divide your exceptions into broad categories to allow your caller to catch great swathes of exceptions easily, including new exceptions you add in future versions of your module.

Throwable::Factory includes three exception categories that you may use for this purpose. These are implemented as role packages with no associated methods, so can be tested for using the DOES method (see UNIVERSAL).

  • Throwable::Taxonomy::Caller - the caller passed bad or unexpected parameters.

  • Throwable::Taxonomy::Environment - a problem was found in the software's operating environment; e.g. network connection unavailable, lack of disk space.

  • Throwable::Taxonomy::NotImplemented - the caller requested a feature that is not currently implemented, but may be in the future.

It is easy to apply these roles to your exception classes:

use Throwable::Factory
   ErrTooBig   => [qw( $maximum! -notimplemented )],
   ErrTooSmall => [qw( $minimum! -notimplemented )],
;
use Try::Tiny::ByClass;

sub calculation
{
   my $input = shift;
   if ($input > 12) {
      ErrTooBig->throw(
         "Inputs over 12 are not currently supported",
         maximum => 12,
      );
   }
   ...;
}

try {
   calculation(13);
}
catch_case [
   +ErrTooBig                            => sub { warn "Too big!" },
   +ErrTooSmall                          => sub { warn "Too small!" },
   "Throwable::Taxonomy::NotImplemented" => sub { warn $_ },
];

The -notimplemented shortcut expands to -with => ['Throwable::Taxonomy::NotImplemented']. Similarly -caller and -environment shortcuts exist.

(Note the plus signs in the catch_case above; this ensures ErrTooBig and ErrToString are not auto-quoted by the fat comma.)

CAVEATS

Exceptions built by this factory inherit from MooX::Struct; see the CAVEATS section from the MooX::Struct documentation.

BUGS

Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=Throwable-Factory.

SEE ALSO

Exceptions built by this factory inherit from MooX::Struct and compose the Throwable and StackTrace::Auto roles.

This factory is inspired by Exception::Class, and for simple uses should be roughly compatible.

Use Try::Tiny, Try::Tiny::ByClass or TryCatch if you need a try/catch mechanism.

AUTHOR

Toby Inkster <tobyink@cpan.org>.

COPYRIGHT AND LICENCE

This software is copyright (c) 2012-2013 by Toby Inkster.

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

DISCLAIMER OF WARRANTIES

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.