What is the best way to handle a failure in a builder method?
For example:
package MyObj;
use Moose;
use IO::File;
has => \'file_name\' ( is =>
"Best" is subjective, but you'll have to decide which makes more sense in your code:
if you can continue on in your code when the filehandle fails to build (i.e. it is a recoverable condition), the builder should return undef and set the type constraint to 'Maybe[IO::File]'
. That means you'll also have to check for definedness on that attribute whenever using it. You could also check if this attribute got built properly in BUILD
, and choose to take further action at that point (as friedo alluded to in his comment), e.g. calling clear_file_handle if it is undef (since a builder will always assign a value to the attribute, assuming it doesn't die of course).
otherwise, let the builder fail, either by explicitly throwing an exception (which you can opt to catch higher up), or simply returning undef and letting the type constraint fail. Either way your code will die; you just get a choice of how it dies and how voluminous the stack trace is. :)
PS. You may also want to look at Try::Tiny, which Moose uses internally, and is basically just a wrapper for* the do eval { blah } or die ...
idiom.
*But done right! and in a cool way! (I seem to hear lots of whispering in my ear from #moose..)