Skip to content

Instantly share code, notes, and snippets.

@fgabolde
Last active December 21, 2015 01:39
Show Gist options
  • Save fgabolde/6229760 to your computer and use it in GitHub Desktop.
Save fgabolde/6229760 to your computer and use it in GitHub Desktop.
A simple exception class that detects when it's being caught.
#!perl
package SmartLoggingException;
use strict;
use warnings;
use 5.010;
use Carp;
use Devel::StackTrace;
use overload '""' => sub { my $self = shift; $self->{message}."\n" };
sub new {
my ($class, %params) = @_;
my $self = { %params };
$self->{message} = "No message set"
unless exists $self->{message};
return bless $self, $class;
}
sub _caught_by_eval_p {
my $self = shift;
my $stacktrace = $self->stacktrace;
die 'Attempted to check stacktrace before stacktrace was set'
unless $stacktrace;
while (my $frame = $stacktrace->prev_frame) {
if ($frame->subroutine eq '(eval)'
and not defined $frame->evaltext) {
$stacktrace->reset_pointer;
return 1;
}
if ($frame->subroutine eq 'SmartLoggingException::throw') {
$stacktrace->reset_pointer;
return;
}
}
$stacktrace->reset_pointer;
return;
}
sub stacktrace {
my ($self, $stacktrace) = @_;
$self->{_stacktrace} = $stacktrace if $stacktrace;
return $self->{_stacktrace};
}
sub throw {
my $self = shift;
$self->stacktrace(Devel::StackTrace->new);
unless ($self->_caught_by_eval_p) {
carp 'I died and no one caught me!';
}
die $self;
}
package main;
use strict;
use warnings;
use 5.010;
use Carp;
use Data::Dumper;
sub do_the_foobar_dance {
my $oops = SmartLoggingException->new(message => 'Please catch me quickly!');
eval { $oops->throw };
if (my $exception = $@) {
print "caught $exception";
$exception->throw; # creates a new stack trace;
}
}
do_the_foobar_dance;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment