Nobody really turned to part of the βbest practice,β so I'll move on.
Yes, you should definitely throw an exception in your code if something goes wrong, and you should do it as soon as possible (so you limit the code that needs to be debugged to find out what causes it).
Code that does things like return undef to indicate failure is not particularly reliable, simply because people will use it without checking the undef value of returnvalue - this means that the variable they assume has something meaningful in reality, This leads to complex, difficult to debug problems, and even unexpected problems that arise later in previously running code.
A firmer approach is to write your code so that it dies if something goes wrong, and only when you need to restore it, wrap any calls in eval{ .. } (or, better, try { .. } catch { .. } from Try :: Tiny , as already mentioned). In most cases, there will be nothing meaningful that the call code can do to restore, so the call code remains simple in the general case, and you can simply assume that you get a useful value. If something goes wrong, then you will get an error message from the actual part of the code that failed, instead of quietly getting undef. If your calling code can do something to recover from failures, it can organize an exception catch and do whatever it needs.
Something worth reading is the exception classes , which are a structured way to send additional information to the calling code, and also allow you to choose which exceptions he wants to catch and which he cannot handle. You probably won't want to use them everywhere in your code, but they are useful when you have something complicated that can fail in equally complex ways and you want the failures to be restored.
source share