Created
July 23, 2011 20:14
-
-
Save eevee/1101832 to your computer and use it in GitHub Desktop.
exception handling comparison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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