Skip Menu |

This queue is for tickets about the Brick CPAN distribution.

Report information
The Basics
Id: 27252
Status: new
Priority: 0/
Queue: Brick

People
Owner: Nobody in particular
Requestors: agianni [...] buffalo.edu
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.225_02
Fixed in: (no value)



Subject: fatal programming errors lost in __compose_pass_or_stop and __compose_pass_or_skip
Fatal programming errors are caught nicely when running a simple brick directly or composing bricks with __and and __or, but error messages are lost when composing bricks with __compose_pass_or_skip and __compose_pass_or_stop. The program_error entry in the results hash shows up, but the message hash entry is empty. See the attached test for examples. The change to__compose_pass_or_skip is simple, change Brick::Composers line 258: die if( ref $eval_error ); to: die if( $eval_error ); __compose_pass_or_stop is a little more confusing. The problem is that if the brick dies with a message, that message ends up in $result and since this (line 334): next if $result; comes before this (line 340): die if( ref $at and $at ); # die for program errors We never get a chance to die. I moved line 340 up above line 334 and changed it to: die if( $at ); # die for program errors which seems to have take care of the problem without breaking anything. Even so, the logic in __compose_pass_or_stop needs review. I think it can actually be simplified into: my $sub = $bucket->add_to_bucket( { code => sub { my $last_result; foreach my $sub ( @subs ) { no warnings 'uninitialized'; $last_result = eval { $sub->( @_ ) }; my $at = $@; die $at if $at; # throw an exception next if $last_ result; # continue if success return; # error but no fatal error }; return $last_result; }, });
Subject: fatals.t
#!/usr/local/bin/perl use strict; use warnings; use ACS::SetLibs qw( eptf ); use Test::More tests => 19; use_ok( 'Brick' ); use_ok( 'Brick::Profile' ); my $brick = Brick->new(); isa_ok( $brick, 'Brick' ); for ( qw( composed_posk composed_post composed_and composed_or ) ) { my $profile = Brick::Profile->new( $brick, [ [ test => $_ => {} ] ] ); isa_ok( $profile, 'Brick::Profile' ); my $result = $brick->apply( $profile, {} ); isa_ok( $result, 'Brick::Result' ); ok( defined $result->[0]->[3]->{program_error}, 'program error caught' ); like( $result->[0]->[3]->{message}, qr/\Acheck for this/, "got correct error message with $_" ); } sub Brick::Bucket::test_brick{ my ( $bucket, $setup ) = @_; return $bucket->add_to_bucket( { code => sub { die 'check for this'; return 1; }, } ); } sub Brick::Bucket::composed_posk{ my ( $bucket, $setup ) = @_; return $bucket->__compose_pass_or_skip( $bucket->test_brick, ); } sub Brick::Bucket::composed_post{ my ( $bucket, $setup ) = @_; return $bucket->__compose_pass_or_stop( $bucket->test_brick, ); } sub Brick::Bucket::composed_and{ my ( $bucket, $setup ) = @_; return $bucket->__and( $bucket->test_brick, ); } sub Brick::Bucket::composed_or{ my ( $bucket, $setup ) = @_; return $bucket->__or( $bucket->test_brick, ); }