Fix missing handling of on_(dis)connect* failures
[dbsrgits/DBIx-Class.git] / t / storage / error.t
CommitLineData
a4b2f17b 1use strict;
a4b2f17b 2use warnings;
3
56166f36 4use Test::More;
5use Test::Warn;
6use Test::Exception;
a4b2f17b 7
8use lib qw(t/lib);
0d8817bc 9use DBICTest;
56166f36 10
0f69bb8b 11for my $conn_args (
12 [ on_connect_do => "_NOPE_" ],
13 [ on_connect_call => sub { shift->_dbh->do("_NOPE_") } ],
14 [ on_connect_call => "_NOPE_" ],
15) {
16 for my $method (qw( ensure_connected _server_info _get_server_version _get_dbh )) {
17
18 my $s = DBICTest->init_schema(
19 no_deploy => 1,
20 on_disconnect_call => sub { fail 'Disconnector should not be invoked' },
21 @$conn_args
22 );
23
24 my $storage = $s->storage;
25 $storage = $storage->master
26 if $storage->isa('DBIx::Class::Storage::DBI::Replicated');
27
28 ok( ! $storage->connected, 'Starting unconnected' );
29
30 my $desc = "calling $method with broken on_connect action @{[ explain $conn_args ]}";
31
32 throws_ok { $storage->$method }
33 qr/ _NOPE_ \b/x,
34 "Throwing correctly when $desc";
35
36 ok( ! $storage->connected, "Still not connected after $desc" );
37
38 # this checks that the on_disconect_call FAIL won't trigger
39 $storage->disconnect;
40 }
41}
42
43for my $conn_args (
44 [ on_disconnect_do => "_NOPE_" ],
45 [ on_disconnect_call => sub { shift->_dbh->do("_NOPE_") } ],
46 [ on_disconnect_call => "_NOPE_" ],
47) {
48 my $s = DBICTest->init_schema( no_deploy => 1, @$conn_args );
49
50 my $storage = $s->storage;
51 $storage = $storage->master
52 if $storage->isa('DBIx::Class::Storage::DBI::Replicated');
53
54 my $desc = "broken on_disconnect action @{[ explain $conn_args ]}";
55
56 # connect + ping
57 my $dbh = $storage->dbh;
58
59 ok ($dbh->FETCH('Active'), 'Freshly connected DBI handle is healthy');
60
61 warnings_exist { eval { $storage->disconnect } } [
62 qr/\QDisconnect action failed\E .+ _NOPE_ \b/x
63 ], "Found warning of failed $desc";
64
65 ok (! $dbh->FETCH('Active'), "Actual DBI disconnect was not prevented by $desc" );
66}
67
e60dc79f 68my $schema = DBICTest->init_schema;
a4b2f17b 69
56166f36 70warnings_are ( sub {
b720efd1 71 throws_ok (
72 sub {
73 $schema->resultset('CD')->create({ title => 'vacation in antarctica' })
74 },
ed5550d3 75 qr/DBI Exception.+(?x:
76 \QNOT NULL constraint failed: cd.artist\E
77 |
78 \Qcd.artist may not be NULL\E
79 )/s
b720efd1 80 ); # as opposed to some other error
56166f36 81}, [], 'No warnings besides exception' );
a4b2f17b 82
b720efd1 83my $dbh = $schema->storage->dbh;
84
85throws_ok (
86 sub {
87 $dbh->do ('INSERT INTO nonexistent_table VALUES (1)')
88 },
0007aedf 89 qr/DBI Exception.+no such table.+nonexistent_table/s,
b720efd1 90 'DBI exceptions properly handled by dbic-installed callback'
91);
92
68fe9141 93# This usage is a bit unusual but it was actually seen in the wild
b720efd1 94# destruction of everything except the $dbh should use the proper
95# exception fallback:
96
cc1924ac 97SKIP: {
8d73fcd4 98 if ( !!DBIx::Class::_ENV_::PEEPEENESS ) {
cc1924ac 99 skip "Your perl version $] appears to leak like a sieve - skipping garbage collected \$schema test", 1;
100 }
101
b720efd1 102 undef ($schema);
103 throws_ok (
104 sub {
105 $dbh->do ('INSERT INTO nonexistent_table VALUES (1)')
106 },
0007aedf 107 qr/DBI Exception.+unhandled by DBIC.+no such table.+nonexistent_table/s,
b720efd1 108 'callback works after $schema is gone'
109 );
110}
111
56166f36 112done_testing;