Ensure the stack properly deals and warns on Null-Pattern exception objects
[dbsrgits/DBIx-Class.git] / t / 34exception_action.t
CommitLineData
4ffbc1d6 1use strict;
f54428ab 2use warnings;
4ffbc1d6 3
4use Test::More;
c3e9f718 5use Test::Exception;
6use Test::Warn;
4ffbc1d6 7use lib qw(t/lib);
8use DBICTest;
9
4ffbc1d6 10# Set up the "usual" sqlite for DBICTest
11my $schema = DBICTest->init_schema;
12
13# This is how we're generating exceptions in the rest of these tests,
14# which might need updating at some future time to be some other
15# exception-generating statement:
16
65d35121 17my $throw = sub { $schema->resultset("Artist")->search(1,1,1) };
4ffbc1d6 18my $ex_regex = qr/Odd number of arguments to search/;
19
20# Basic check, normal exception
65d35121 21throws_ok \&$throw, $ex_regex;
c3e9f718 22
23my $e = $@;
b2f408f3 24
25# Re-throw the exception with rethrow()
c3e9f718 26throws_ok { $e->rethrow }
27 $ex_regex;
b2f408f3 28isa_ok( $@, 'DBIx::Class::Exception' );
4ffbc1d6 29
30# Now lets rethrow via exception_action
4f29a592 31{
32 my $handler_execution_counter = 0;
33
34 $schema->exception_action(sub {
35 $handler_execution_counter++;
36 like $_[0], $ex_regex, "Exception is precisely passed to exception_action";
37 die @_
38 });
39
40 throws_ok \&$throw, $ex_regex;
41 is $handler_execution_counter, 1, "exception_action handler executed exactly once";
42}
4ffbc1d6 43
c3e9f718 44#
45# This should have never worked!!!
46#
4ffbc1d6 47# Now lets suppress the error
48$schema->exception_action(sub { 1 });
65d35121 49throws_ok \&$throw,
c3e9f718 50 qr/exception_action handler .+ did \*not\* result in an exception.+original error: $ex_regex/;
4ffbc1d6 51
52# Now lets fall through and let croak take back over
53$schema->exception_action(sub { return });
c3e9f718 54throws_ok {
65d35121 55 warnings_are \&$throw,
c3e9f718 56 qr/exception_action handler installed .+ returned false instead throwing an exception/;
57} $ex_regex;
58
59# again to see if no warning
60throws_ok {
65d35121 61 warnings_are \&$throw,
c3e9f718 62 [];
63} $ex_regex;
64
4ffbc1d6 65
66# Whacky useless exception class
67{
68 package DBICTest::Exception;
69 use overload '""' => \&stringify, fallback => 1;
70 sub new {
71 my $class = shift;
72 bless { msg => shift }, $class;
73 }
74 sub throw {
75 my $self = shift;
76 die $self if ref $self eq __PACKAGE__;
77 die $self->new(shift);
78 }
79 sub stringify {
80 "DBICTest::Exception is handling this: " . shift->{msg};
81 }
82}
83
84# Try the exception class
85$schema->exception_action(sub { DBICTest::Exception->throw(@_) });
65d35121 86throws_ok \&$throw,
c3e9f718 87 qr/DBICTest::Exception is handling this: $ex_regex/;
4ffbc1d6 88
89# While we're at it, lets throw a custom exception through Storage::DBI
c3e9f718 90throws_ok { $schema->storage->throw_exception('floob') }
91 qr/DBICTest::Exception is handling this: floob/;
9bf06dc0 92
84e4e006 93# test antipatterns
94for my $ap (qw(
95 DBICTest::AntiPattern::TrueZeroLen
96 DBICTest::AntiPattern::NullObject
97)) {
98 eval "require $ap";
99 my $exp_warn = qr/\QObjects of external exception class '$ap' stringify to '' (the empty string)/;
100
101 # make sure an exception_action can replace $@ with an antipattern
102 $schema->exception_action(sub { die $ap->new });
103 warnings_like {
104 eval { $throw->() };
105 isa_ok $@, $ap;
106 } $exp_warn, 'proper warning on antipattern encountered within exception_action';
107
108 # and make sure that the retrhow works
109 $schema->exception_action(sub { die @_ });
110 warnings_like {
111 eval {
112 $schema->txn_do (sub { die $ap->new });
113 };
114
115 isa_ok $@, $ap;
116 } $exp_warn, 'Proper warning on encountered antipattern';
117}
118
68fe9141 119done_testing;