From 9391d36473ae8aff0ba6179957ed52bf546e2c24 Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Mon, 23 Mar 2026 11:12:17 +0100 Subject: [PATCH] Fix Try::Tiny::catch when called as method via namespace pollution When namespace::autoclean doesn't clean up Try::Tiny imports (as in PerlOnJava's stub), modules like DateTime retain 'catch' in their namespace. This causes issues when indirect object syntax like 'catch { $dt->truncate(...) }' is parsed as '$dt->truncate(...)->catch()'. The fix detects when catch() is incorrectly invoked as a method (first argument is a blessed reference instead of CODE) and throws the expected 'Can't locate object method' error, making tests like DateTime's t/48rt-115983.t pass. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- src/main/perl/lib/Try/Tiny.pm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/perl/lib/Try/Tiny.pm b/src/main/perl/lib/Try/Tiny.pm index 4dbc60d93..ffdad06d8 100644 --- a/src/main/perl/lib/Try/Tiny.pm +++ b/src/main/perl/lib/Try/Tiny.pm @@ -26,6 +26,16 @@ BEGIN { # Blessed wrapper for catch blocks sub catch (&;@) { my ($block, @rest) = @_; + + # Detect incorrect method call (e.g., $obj->catch(...) when namespace::autoclean + # didn't clean up Try::Tiny imports). This happens with indirect object syntax: + # "catch { $dt->truncate(...) }" is parsed as "$dt->truncate(...)->catch()" + # when 'catch' is in the invocant's package namespace. + if (ref($block) && ref($block) ne 'CODE') { + my $pkg = ref($block); + croak qq{Can't locate object method "catch" via package "$pkg" (perhaps you forgot to load "$pkg"?)}; + } + # Detect bare catch() in void context croak 'Useless bare catch()' unless wantarray; # Name the block if we can