Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Help with Try::Tiny and Catalyst::Authentication::Realm::Progressive

by ghenry (Vicar)
on Dec 13, 2011 at 00:03 UTC ( [id://943212]=perlquestion: print w/replies, xml ) Need Help??

ghenry has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

Been a while. I've been banging my head for ages and can't work out why changing the following makes prove fail

[http://cpansearch.perl.org/src/BOBTFISH/Catalyst-Plugin-Authenticatio +n-0.10018/lib/Catalyst/Authentication/Realm/Progressive.pm] if ( my $obj = $realm->authenticate( $c, $auth ) ) { $c->set_authenticated( $obj, $realm->name ); return $obj; } Changes: 139 my $auth_obj; 140 my $error = try { 141 $auth_obj = $realm->authenticate( $c, $auth ); 142 } 143 catch { return $_; }; 144 145 if ($auth_obj) { 146 $c->set_authenticated( $auth_obj, $realm->name ); 147 return $auth_obj; 148 }

[ghenry@dax-xen Catalyst-Plugin-Authentication]$ cat t/live_app_realms +_progressive.t use strict; use warnings; use Test::More; use lib 't/lib'; use Catalyst::Test qw/AuthRealmTestAppProgressive/; ok(get("/progressive"), "get ok"); done_testing; [ghenry@dax-xen Catalyst-Plugin-Authentication]$ cat t/lib/AuthRealmTe +stAppProgressive/Controller/Root.pm package AuthRealmTestAppProgressive::Controller::Root; use warnings; use strict; use base qw/Catalyst::Controller/; __PACKAGE__->config(namespace => ''); use Test::More; use Test::Exception; sub progressive : Local { my ( $self, $c ) = @_; foreach my $realm ( keys %AuthRealmTestAppProgressive::members ) { while ( my ( $user, $info ) = each %{$AuthRealmTestAppProgress +ive::members{$realm}} ) { my $ok = eval { $c->authenticate( { username => $user, password => $info->{password} + }, ); }; diag $@; diag $ok; ok( !$@, "authentication passed." ); ok( $ok, "user authenticated" ); ok( $c->user_in_realm($realm), "user in proper realm" ); } } $c->res->body( "ok" ); } 1; [ghenry@dax-xen Catalyst-Plugin-Authentication]$ prove -l t/live_app_r +ealms_progressive.t t/live_app_realms_progressive.t .. # # undef t/live_app_realms_progressive.t .. 1/? # Failed test 'user authenticated' # at t/lib/AuthRealmTestAppProgressive/Controller/Root.pm line 24. # Failed test 'user in proper realm' # at t/lib/AuthRealmTestAppProgressive/Controller/Root.pm line 25. # # undef # Failed test 'user authenticated' # at t/lib/AuthRealmTestAppProgressive/Controller/Root.pm line 24. # Looks like you failed 3 tests of 7. t/live_app_realms_progressive.t .. Dubious, test returned 3 (wstat 768 +, 0x300) Failed 3/7 subtests Test Summary Report ------------------- t/live_app_realms_progressive.t (Wstat: 768 Tests: 7 Failed: 3) Failed tests: 2-3, 5 Non-zero exit status: 3 Files=1, Tests=7, 7 wallclock secs ( 0.09 usr 0.00 sys + 4.14 cusr + 0.09 csys = 4.32 CPU) Result: FAIL

I'm trying to patch Catalyst::Authentication::Realm::Progressive to allow multiple realms with Basic HTTP auth, as the credential HTTP plugin calls ->detach which means other realms never get tried.
Thanks.

Walking the road to enlightenment... I found a penguin and a camel on the way.....
Fancy a yourname@perl.me.uk? Just ask!!!

Replies are listed 'Best First'.
Re: Help with Try::Tiny and Catalyst::Authentication::Realm::Progressive (catch { return })
by tye (Sage) on Dec 13, 2011 at 00:30 UTC

    You can't make your outer sub return by saying 'return' within the (implied) sub that you passed to 'catch'. catch { return } is the same as &catch( sub { return } ) so the 'return' simply returns from the anonymous sub.

    - tye        

      Thanks. I've realised that from the docs and doing more tests now, but why, without catch does $auth_obj = $realm->authenticate( $c, $auth ); not work as expected like the original code? Nothing else has changed.

      Walking the road to enlightenment... I found a penguin and a camel on the way.....
      Fancy a yourname@perl.me.uk? Just ask!!!
Re: Help with Try::Tiny and Catalyst::Authentication::Realm::Progressive (local $@)
by tye (Sage) on Dec 13, 2011 at 07:42 UTC

    By running it through prove instead of just running it directly, you make it harder to understand the output. But...

    my $ok = eval { $c->authenticate( { username => $user, password => $info->{password} + }, ); }; diag $@; diag $ok; [...] t/live_app_realms_progressive.t t/live_app_realms_progressive.t .. # # undef [...] # # undef

    Shows that the eval is failing (setting $ok to undef) but also leaving $@ as the empty string. Devel::EvalError explains how this can happen -- some of this has changed in the most recent versions of Perl (somewhat for the better, somewhat for the worse).

    Devel::EvalError will even add a __DIE__ handler for you so that you can see the lost $@ value. The syntax of that module is stupidly ugly (the author was foolishly thinking that he had to avoid 'try { ... }' syntax because you can't "return" from it when the fact is that you can't "return" from 'eval { ... }' in exactly the same way and what he needed to avoid was only the obnoxious 'catch { ... }' syntax), so you can also just add your own __DIE__ handler simply enough.

    Update: Oops. That is only one possible explanation. But it is more likely that the method call is just returning undef. I'd write that as:

    my $res; my $ok= eval { $res= $c->...; 1; };

    so the distinction is clear.

    - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://943212]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2024-03-29 06:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found