Question

I'm am using carp in a Try::Tiny catch block, and it always reports the error from the wrong location. The documentation for Try::Tiny says that it adds itself to %Carp::Internal so that it doesn't appear in longer backtraces. But it still appears in the summary line. The documentation for Carp says that adding a package name to %Carp::CarpInternal will remove the package from both the stack trace and the summary line. So I've done that, but the reported location is still incorrect. Here's the code I'm working with:

MyPackage::foo();

package MyPackage;
use Try::Tiny;
use Carp;
use vars qw(%Carp::CarpInternal);
$Carp::CarpInternal{'Try::Tiny'}++;

use Data::Dumper;
print Dumper \%Carp::CarpInternal;
print Dumper \%Carp::Internal;

sub foo {
    carp 'bar1';
    try{
        carp 'bar2'
    }catch {
        carp $_;
    }
}

1;

And here's what it prints:

bar1 at myFile.t line 1.
bar2 at myFile.t line 21.
$VAR1 = {
      'Try::Tiny' => 1,
      'warnings' => 1,
      'Carp' => 1
    };
$VAR1 = {
      'Try::Tiny' => 1,
      'Exporter::Heavy' => 1,
      'Exporter' => 1
    };

The two variables are what I expect them to be, but I want the errors to both be reported at line 1 of myFile.t. Does anyone know how to fix the error reporting location to be what I want?

Was it helpful?

Solution

In my experiment, this solution only works when the caller comes from a different file. Adding Try::Tiny to the @CARP_NOT variable for the package fixes in this case:

#first file
use MyPackage;
MyPackage::foo();

#second file
package MyPackage;
use Carp qw(carp cluck);
our @CARP_NOT = qw(Try::Tiny);
use Try::Tiny;

sub foo {
    carp 'bar1';
    cluck 'bar2';
    try{
        carp 'bar3'
    }catch {
        cluck $_;
    }
}
1;

It prints the following:

bar1 at myFile.t line 2.
bar2 at MyPackage.pm line 8.
        MyPackage::foo() called at myFile.t line 2
bar3 at myFile.t line 2.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top