Developer time is expensive, while machine time is becoming
increasingly cheap. There are still development niches where
squeezing every bit of performance out of the system is desirable, but
more often then not it is better to implement code that is easy to
maintain and facillitates the rapid detection and repair of code
defects. Robust exception handling is at the core of this matter, and
while Perl offers decent exception handling capabilities, it is not
always clear the route to take.
At the simplest level, there is the eval/die idiom in which one wraps
some code up in an eval block that may throw exceptions (try), and
then afterward tests $@ and dies with some informative message should
it be defined (catch). Just adding this simple methodology to one's code can
be enormously helpful, but there are very different contexts in which
one might want to throw exceptions, and accordingly different ways
that may be appropriate. The Carp module offers some alternatives to
'die' with 'croak' and 'confess'.
Different exceptional cases may include invalid arguments passed to a
subroutine, the unavailability of a file system or network resource, a
subroutine in apparent violation of its contract, and many others.
The error may have originated deep within underlying libraries, or it
may be occuring right below the public interface of a class.
Depending on the situation, it may be advantageous to throw an
exception from the perspective of the caller, or to include a stack
trace. One may also want to rethrow the exception to a higher level
with additional information.
The correct route in some situations is more obvious than others. In
the case of invalid arguments, it is probably advantageous to make the
exception appear from the context of the caller with a helpful
message such as "argument two was totally bogus, bozo!" In other
scenarios, the best mechanism is less obvious. Always including a
stack trace may seem advantageous at first glance, but in some
contexts it may prove misleading, adding extra noise to the debug info
and thus hindering detective work.
This would seem to be one of those things where there is WAY more than
one way to do it, so I'd love to hear the heuristics that fellow Perl
Mongers employ in their own daily coding when deciding on how to handle
exceptions.