From 2c9023287b47451bac3956d14e48e838e321ad2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Thu, 26 Feb 2026 22:52:53 -0700 Subject: [PATCH] Do not warn on false-but-blessed exceptions in dies() Blessed objects that overload to a false boolean result are legitimate exceptions and should not trigger the falsy-exception warning. This changes the guard from `unless ($err)` to `unless (ref($err) or $err)` so that any reference (blessed or not) bypasses the warning. Also adds documentation in the DIFFERENCES FROM TEST::FATAL section noting this behavioral distinction, and a regression test using an overloaded object. Recreated from Test-More/test-more#1020 with feedback from haarg and exodist incorporated (doc update + test). --- lib/Test2/Tools/Exception.pm | 8 +++++++- t/modules/Tools/Exception.t | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/Test2/Tools/Exception.pm b/lib/Test2/Tools/Exception.pm index 6681224ac..d4761583a 100644 --- a/lib/Test2/Tools/Exception.pm +++ b/lib/Test2/Tools/Exception.pm @@ -21,7 +21,7 @@ sub dies(&) { return undef if $ok; - unless ($err) { + unless (ref($err) or $err) { my $ctx = context(); $ctx->alert("Got exception as expected, but exception is falsy (undef, '', or 0)..."); $ctx->release; @@ -139,6 +139,12 @@ disagree with this, and think the actual line of the failing test is more important. Ultimately, though L cannot be changed, people probably already depend on that behavior. +L will die if the exception is a false value (C, C<''>, or +C<0>). C will instead warn and return the false exception. Additionally, +C will B warn when the exception is a blessed object that evaluates +to false (e.g. via overloaded boolification), since this is a legitimate use +case for objects that use boolean overloading to indicate success or failure. + =head1 SOURCE The source code repository for Test2-Suite can be found at diff --git a/t/modules/Tools/Exception.t b/t/modules/Tools/Exception.t index 805549d9c..6780a792e 100644 --- a/t/modules/Tools/Exception.t +++ b/t/modules/Tools/Exception.t @@ -42,6 +42,19 @@ is( like($err, qr/abc/, '$@ has the exception'); +# Test that blessed objects overloading to false do not trigger the falsy warning +{ + package FalseException; + use overload bool => sub { 0 }, '""' => sub { "false exception object" }, fallback => 1; + sub new { bless {}, shift } +} + +my $false_obj = FalseException->new(); + +my $got; +is(warning { $got = dies { die $false_obj } }, undef, "no warning for blessed false exception"); +isa_ok($got, ['FalseException'], "dies() returns the blessed false exception object"); + like( warning { dies { 1 } }, qr/Useless use of dies\(\) in void context/,