200 Moose exception classes. ◮ Making Moose throw instances of those exception classes. ◮ Test cases & documentation for all those 200 Moose exceptions. ◮ In short, 368 changed files with 23,830 additions and 1,479 deletions. ◮ I’m not crazy! I didn’t do it for free. ◮ GNOME foundation & The Perl Foundation paid me 5000 USD for this work :).
as women or cis or trans to get involved in free and open source software. ◮ Tasks involve coding, testing, documentation, marketing, community management, support etc. ◮ Wikimedia, Linux Kernel, OpenStack Foundation and Mozilla are some of the regular participants (Perl participated only twice :) ). ◮ Moose structured exceptions were done via OPW, by me under mentorship of Shawn Moore and Jesse Luehrs.
Moose; 4 5 # name is required \& should be a String 6 has ’name ’ => ( 7 is => ’ro’, 8 isa => ’Str’, 9 required => 1, 10 ); 11 12 # age is required \& should be an Integer 13 has ’age ’ => ( 14 is => ’ro’, 15 isa => ’Int’, 16 required => 1, 17 ); 18 }
3 { 4 my $person = Person ->new( 5 name => "Mr. Moose", 6 age => "xyz", 7 ); 8 } 9 catch 10 { 11 my $exception = $_; 12 if( $exception =~ /\ QAttribute (age) does not pass the type constraint because :/ ) 13 { 14 # I’m not going to parse the error message for displaying the incorrect age! 15 die "What! Your age is ....? :P"; 16 } 17 elsif( $exception =~ /\ QAttribute (age) is required/ ) 18 { 19 die "Why didn ’t you give age?"; 20 } 21 #... 22 };
someone changes the error message, then your error handling code is useless. ◮ Want more error information? ◮ Use Carp::Always. ◮ Parse the error message. ◮ Have more if-else blocks. ◮ Use structured exceptions.
Moose; 4 5 # name is required \& should be a String 6 has ’name ’ => ( 7 is => ’ro’, 8 isa => ’Str’, 9 required => 1, 10 ); 11 12 # age is required \& should be an Integer 13 has ’age ’ => ( 14 is => ’ro’, 15 isa => ’Int’, 16 required => 1, 17 ); 18 }
used in catch block ◮ Some exception classes does common Roles. ◮ So ->does(’Moose::Exception::Role::Class) can be used instead where you’re expecting two different exceptions which have a common Role Moose::Exception::Role::Class. ◮ Ability to improve exception messages freely ◮ Once, all the modules dependent on Moose change their code to use exception objects, we can easily improve exception messages.
stack trace for custom error handling since it’s a Devel::StackTrace object. ◮ It’s now much easier to override how Moose formats errors ◮ Now error formatting is just in one place: Moose::Exception. ◮ Previously there were calls to confess, croak, and die all over the Moose codebase. ◮ Documentation of exception types
A bit heavy, 200 files... ◮ A bit slow, but we have tried to avoid it by loading specific classes at runtime. ◮ You need to create a new file for every new exception. ◮ Polluted MetaCPAN search results, because of 200 exception classes, but it can be solved. ◮ Perl’s built in exceptions are strings, and everybody is already used to them.
classes. ◮ provides a throw method. ◮ comes with Throwable::Error, which is a basic error class ◮ adds stack trace handling, one-arg constructor, stringification
like: ◮ ”Cannot have an isa option and a does option if the isa does not do the does on attribute (”.$self->attribute name.”)”; ◮ Factoring out common behaviour among exception classes and making roles for them. ◮ Making user-defined exceptions work with Moose. ◮ As of now, Moose::Util::throw exception works with Moose::Exception::* ◮ But it should also work with exceptions having different namespace. ◮ Structured exceptions were the first, very tedious step toward improving Moose’s error formatting
trace looks like: 1 Attribute (age) is required at lib/Moose/Exception.pm line 32 2 Moose :: Exception :: _build_trace (’Moose :: Exception :: AttributeIsRequired =HA 3 SH(0 x208b760)’) called at reader Moose :: Exception :: trace (defined at 4 lib/Moose/Exception.pm line 6) line 7 5 ... 6 eval {...} at 7 /home/upasana/perl5/perlbrew/perls/perl -5.18.0/ lib/site_perl /5.18.0/ Try/ 8 Tiny.pm line 74 9 Try:: Tiny ::try(’CODE (0 x1effca0)’, ’Try:: Tiny :: Catch=REF(0 x208b940)’) 10 called at /home/upasana/Test/Perl/ test_two_errors .pl line 54 ◮ Useful information is at the bottom of the stack trace. ◮ We can make it better by playing with Carp level, though it’s a bit complex. ◮ Carp::Clan and may be some other modules could be of some help in this.
handling code from his talk. ◮ Shawn Moore and Chris Prather - For reviewing this talk. ◮ Tobias Oetiker - For suggesting me to add in-band errors. ◮ Yuval Kogman - I stole some disadvantages of structured exceptions from his blog : http://blog.woobling.org/2010/07/are-we-ready-to-ditch- ◮ #moose-dev on irc.perl.org - For helping me with some of structured exceptions code. ◮ For in-band errors - https://www.securecoding.cert.org/confluence/display/se ◮ For autodie : https://metacpan.org/pod/autodie ◮ Inspiration behind the title of this talk - Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb