A discussion in another question got me wondering: what do other programming languages' exception systems have that Perl's lacks?
Perl's built-in exceptions are a bit ad-hoc in that they were, like the Perl 5 object system, sort-of bolted on as an afterthought, and they overload other keywords (eval
and die
) which are not dedicated specifically to exceptions.
The syntax can be a little ugly, compared to languages with builtin try/throw/catch type syntax. I usually do it like this:
eval { do_something_that_might_barf(); }; if ( my $err = $@ ) { # handle $err here }
There are several CPAN modules that provide syntactic sugar to add try/catch keywords and to allow the easy declaration of exception class hierarchies and whatnot.
The main problem I see with Perl's exception system is the use of the special global $@
to hold the current error, rather than a dedicated catch
-type mechanism that might be safer, from a scope perspective, though I've never personally run into any problems with $@
getting munged.
If an exception occurs within the try block, then it is handled by the appropriate exception handler (catch block), associated with the try block. If no exceptions are thrown, then try will return the result of block. A try block should have at least one (or more) catch block(s) or one finally block.
Don't use exceptions to signal something completely normal. Don't use exceptions to control your normal application flow. Use return values or state fields for flow control instead.
Exceptions provide the means to separate the details of what to do when something out of the ordinary happens from the main logic of a program. In traditional programming, error detection, reporting, and handling often lead to confusing spaghetti code.
The typical method most people have learned to handle exceptions is vulnerable to missing trapped exceptions:
eval { some code here }; if( $@ ) { handle exception here };
You can do:
eval { some code here; 1 } or do { handle exception here };
This protects from missing the exception due to $@
being clobbered, but it is still vulnerable to losing the value of $@
.
To be sure you don't clobber an exception, when you do your eval, you have to localize $@
;
eval { local $@; some code here; 1 } or do { handle exception here };
This is all subtle breakage, and prevention requires a lot of esoteric boilerplate.
In most cases this isn't a problem. But I have been burned by exception eating object destructors in real code. Debugging the issue was awful.
The situation is clearly bad. Look at all the modules on CPAN built provide decent exception handling.
Overwhelming responses in favor of Try::Tiny combined with the fact that Try::Tiny is not "too clever by half", have convinced me to try it out. Things like TryCatch and Exception::Class::TryCatch, Error, and on and on are too complex for me to trust. Try::Tiny is a step in the right direction, but I still don't have a lightweight exception class to use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With