Skip to content

Instantly share code, notes, and snippets.

@eevee
Created July 23, 2011 20:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eevee/1101832 to your computer and use it in GitHub Desktop.
Save eevee/1101832 to your computer and use it in GitHub Desktop.
exception handling comparison
package My::Exception;
use Moose;
use Devel::StackTrace;
use overload
'""' => sub { shift->message };
has message => (
is => 'ro',
isa => 'Str',
);
has stack_trace => (
is => 'ro',
isa => 'Devel::StackTrace',
init_arg => undef,
# Note that in practice, this would want to discard the Moose frames
# involved in creating this object, as well as the $SIG{__DIE__} handler
# itself.
builder => sub { Devel::StackTrace->new },
);
sub BUILD {
my ($message) = @_;
# Moose exceptions come with an entire Carp-ish stack trace built in,
# though in string form, so strip that off carefully...
$message =~ s{ at \S+ line \d+[.].*}{};
return { message => $message };
}
# ...
use Try::Tiny;
sub _sig_die {
my ($err) = @_;
if (not blessed $err) {
die My::Exception->new($err);
}
elsif ($err->isa('My::Exception')) {
die $err;
}
elsif ($err->isa('Template::Exception')) {
# Template Toolkit relies on some properties of its exceptions for
# correct handling, like the "type" which is mostly internal and
# poorly-documented. The only solution I found here was to create a
# common subclass of /both/ My::Exception and Template::Exception.
# That subclass was a travesty and is not shown here.
die My::Exception::TemplateToolkit->new($err);
}
else {
# Some other kind of thrown object.
# DBIx::Class, for example, throws exceptions that stringify to the die
# message. Let's hope everyone else is as polite.
die My::Exception->new("$message");
}
}
sub main {
local $SIG{__DIE__} = \&_sig_die;
try {
do_something();
}
catch {
my $err = $_;
if ($err =~ /Can't do whatever/) {
# ...sigh...
}
}; # don't forget the semicolon
}
class MyException(Exception): pass
def do_something():
raise MyException()
def main():
try:
do_something()
except MyException as e:
print "oh no we got", e
raise
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment