Skip Menu |

This queue is for tickets about the autodie CPAN distribution.

Report information
The Basics
Id: 73316
Status: resolved
Priority: 0/
Queue: autodie

People
Owner: Nobody in particular
Requestors: MAROS [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Custom exception classes
Using custom exception classes for autodie fails if the packages are defined inline and do not reside in a separate file. I have attached a patch with a testcase as well as a possible fix.
Subject: patch.diff
diff --git a/lib/Fatal.pm b/lib/Fatal.pm index aabdf78..c314a2a 100755 --- a/lib/Fatal.pm +++ b/lib/Fatal.pm @@ -1234,13 +1234,7 @@ sub exception_class { return "autodie::exception" }; # actually barewords. As such, we're left doing a string eval # to make sure we load our file correctly. - my $E; - - { - local $@; # We can't clobber $@, it's wrong! - eval "require $exception_class"; ## no critic - $E = $@; # Save $E despite ending our local. - } + my $E = _load_class($exception_class); # We need quotes around $@ to make sure it's stringified # while still in scope. Without them, we run the risk of @@ -1256,6 +1250,35 @@ sub exception_class { return "autodie::exception" }; } } +# Smarter loading of exception classes + +sub _load_class { + my ($class) = @_; + + { + no strict 'refs'; + + # Handle by far the two most common cases + # This is very fast and handles 99% of cases. + return if defined ${"${class}::VERSION"}; + return if defined @{"${class}::ISA"}; + + # Are there any symbol table entries other than other namespaces + foreach ( keys %{"${class}::"} ) { + next if substr($_, -2, 2) eq '::'; + return if defined &{"${class}::$_"}; + } + } + + local $@; # We can't clobber $@, it's wrong! + + my $pm_file = $class . ".pm"; + $pm_file =~ s{ (?: :: | ' ) }{/}gx; + eval { require $pm_file }; + + return $@; # Return $E despite ending our local. +} + # For some reason, dying while replacing our subs doesn't # kill our calling program. It simply stops the loading of # autodie and keeps going with everything else. The _autocroak
Ticket migrated to github as https://github.com/pjf/autodie/issues/92