From: Peter Rabbitson Date: Thu, 4 Jul 2013 06:45:13 +0000 (+0200) Subject: Sanity check erroneous invocations X-Git-Tag: Try-Tiny-0.13~6^2~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9d0e04660c421c7e2be49ff45bca0ff8599be7ce;p=p5sagit%2FTry-Tiny.git Sanity check erroneous invocations --- diff --git a/Changes b/Changes index fd0aac1..0b1704a 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,8 @@ - fix tests failing on 5.6.x due to differing DESTROY semantics - excise superfluous local($@) call - 7% speedup - fix (fsvo) broken URLs (RT#55659) + - proper exception on erroneous usage of bare catch/finally (RT#81070) + - proper exception on erroneous use of multiple catch{} blocks 0.12 - doc fixes diff --git a/lib/Try/Tiny.pm b/lib/Try/Tiny.pm index 5aaeae2..3056c4c 100644 --- a/lib/Try/Tiny.pm +++ b/lib/Try/Tiny.pm @@ -33,6 +33,8 @@ sub try (&;@) { my $ref = ref($code_ref); if ( $ref eq 'Try::Tiny::Catch' ) { + croak 'A try() may not be followed by multiple catch() blocks' + if $catch; $catch = ${$code_ref}; } elsif ( $ref eq 'Try::Tiny::Finally' ) { push @finally, ${$code_ref}; @@ -101,6 +103,8 @@ sub try (&;@) { sub catch (&;@) { my ( $block, @rest ) = @_; + croak 'Useless bare catch()' unless defined wantarray; + return ( bless(\$block, 'Try::Tiny::Catch'), @rest, @@ -110,6 +114,8 @@ sub catch (&;@) { sub finally (&;@) { my ( $block, @rest ) = @_; + croak 'Useless bare finally()' unless defined wantarray; + return ( bless(\$block, 'Try::Tiny::Finally'), @rest, diff --git a/t/erroneous_usage.t b/t/erroneous_usage.t new file mode 100644 index 0000000..c447c61 --- /dev/null +++ b/t/erroneous_usage.t @@ -0,0 +1,48 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More tests => 5; +use Try::Tiny; + +sub _eval { + local $@; + local $Test::Builder::Level = $Test::Builder::Level + 2; + return ( scalar(eval { $_[0]->(); 1 }), $@ ); +} + +sub throws_ok (&$$) { + my ( $code, $regex, $desc ) = @_; + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my ( $ok, $error ) = _eval($code); + + if ( $ok ) { + fail($desc); + } else { + like($error || '', $regex, $desc ); + } +} + +throws_ok { + try { 1 }; catch { 2 }; +} qr/\QUseless bare catch()/, 'Bare catch() detected'; + +throws_ok { + try { 1 }; finally { 2 }; +} qr/\QUseless bare finally()/, 'Bare finally() detected'; + +throws_ok { + try { 1 }; catch { 2 } finally { 2 }; +} qr/\QUseless bare catch()/, 'Bare catch()/finally() detected'; + +throws_ok { + try { 1 }; finally { 2 } catch { 2 }; +} qr/\QUseless bare finally()/, 'Bare finally()/catch() detected'; + + +throws_ok { + try { 1 } catch { 2 } catch { 3 } finally { 4 } finally { 5 } +} qr/\QA try() may not be followed by multiple catch() blocks/, 'Multi-catch detected'; +