package Workflow::Exception; # $Id: Exception.pm 301 2007-07-03 14:54:01Z jonasbn $ use strict; # Declare some of our exceptions... use Exception::Class ( 'Workflow::Exception::Condition' => { isa => 'Workflow::Exception', description => 'Condition failed errors', }, 'Workflow::Exception::Configuration' => { isa => 'Workflow::Exception', description => 'Configuration errors', }, 'Workflow::Exception::Persist' => { isa => 'Workflow::Exception', description => 'Persistence errors', }, 'Workflow::Exception::Validation' => { isa => 'Workflow::Exception', description => 'Validation errors', }, ); use Log::Log4perl qw( get_logger ); my %TYPE_CLASSES = ( condition_error => 'Workflow::Exception::Condition', configuration_error => 'Workflow::Exception::Configuration', persist_error => 'Workflow::Exception::Persist', validation_error => 'Workflow::Exception::Validation', workflow_error => 'Workflow::Exception', ); $Workflow::Exception::VERSION = '1.08'; @Workflow::Exception::ISA = qw( Exporter Exception::Class::Base ); @Workflow::Exception::EXPORT_OK = keys %TYPE_CLASSES; # Exported shortcuts sub _mythrow { my $type = shift @_; my ( $msg, %params ) = _massage( @_ ); my $log = get_logger(); my ( $pkg, $line ) = (caller)[0,2]; my ( $prev_pkg, $prev_line ) = (caller(1))[0,2]; $log->error( "$type exception thrown from [$pkg: $line; before: ", "$prev_pkg: $prev_line]: $msg" ); goto &Exception::Class::Base::throw( $TYPE_CLASSES{ $type }, message => $msg, %params ); } # Use 'goto' here to maintain the stack trace sub condition_error { unshift @_, 'condition_error'; goto &_mythrow; } sub configuration_error { unshift @_, 'configuration_error'; goto &_mythrow; } sub persist_error { unshift @_, 'persist_error'; goto &_mythrow; } sub validation_error { unshift @_, 'validation_error'; goto &_mythrow; } sub workflow_error { unshift @_, 'workflow_error'; goto &_mythrow; } # Override 'throw' so we can massage the message and parameters into # the right format for E::C sub throw { my $class = shift @_; my ( $msg, %params ) = _massage( @_ ); goto &Exception::Class::Base::throw( $class, message => $msg, %params ); } sub _massage { my @items = @_; my %params = ( ref $items[-1] eq 'HASH' ) ? %{ pop( @items ) } : (); my $msg = join( '', @items ); return ( $msg, %params ); } 1; __END__ =head1 NAME Workflow::Exception - Base class for workflow exceptions =head1 SYNOPSIS # Standard usage use Workflow::Exception qw( workflow_error ); my $user = $wf->context->param( 'current_user' ); unless ( $user->check_password( $entered_password ) ) { workflow_error "User exists but password check failed"; } # Pass a list of strings to form the message unless ( $user->check_password( $entered_password ) ) { workflow_error 'Bad login: ', $object->login_attempted; } # Using other exported shortcuts use Workflow::Exception qw( configuration_error ); configuration_error "Field 'foo' must be a set to 'bar'"; use Workflow::Exception qw( validation_error ); validation_error "Validation for field 'foo' failed: $error"; =head1 DESCRIPTION First, you should probably look at L for more usage examples, why we use exceptions, what they are intended for, etc. This is the base class for all workflow exceptions. It declares a handful of exceptions and provides shortcuts to make raising an exception easier and more readable. =head1 METHODS =head3 throw( @msg, [ \%params ]) This overrides B from L to add a little syntactic sugar. Instead of: $exception_class->throw( message => 'This is my very long error message that I would like to pass', param1 => 'Param1 value', param2 => 'Param2 value' ); You can use: $exception_class->throw( 'This is my very long error message ', 'that I would like to pass', { param1 => 'Param1 value', param2 => 'Param2 value' } ); And everything will work the same. Combined with the L this makes for very readable code: workflow_error "Something went horribly, terribly, dreadfully, " "frightfully wrong: $@", { foo => 'bar' }; =head3 condition_error This method transforms the error to a condition error. This exception is thrown via when a condition of a workflow is invalid. =head3 configuration_error This method transforms the error to a configuration error. This exception is thrown via when configuration of a workflow is unsuccessful. =head3 persist_error This method transforms the error to a persistance error. This exception is thrown via when the save of a workflow is unsuccessful. =head3 validation_error This method transforms the error to a validation error. This exception is thrown via when input data or similar of a workflow is unsuccessful. =head3 workflow_error This method transforms the error to a workflow error. This exception is thrown via when input data or similar of a workflow is unsuccessful. =head1 SHORTCUTS B - import using C B - import using C B - import using C B - import using C B - import using C =head1 SEE ALSO L =head1 COPYRIGHT Copyright (c) 2003-2004 Chris Winters. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHORS Chris Winters Echris@cwinters.comE