[Catalyst] Returning error codes to the user.

Matt S Trout mst at shadowcat.co.uk
Sun May 2 19:53:32 GMT 2010


On Fri, Apr 30, 2010 at 04:18:46PM -0700, Bill Moseley wrote:
> I have a CRUD interface to an application.  This is used for both the Web
> and directly as an API.
> 
> The model uses DBIC which, as you know, allows chaining resultsets, which I
> use to add additional constraints to the result set.
> 
> So, a request for, say, /user/1234 might result in:
> 
> $c->model( 'App::User' )->search(
>     {
>         'me.id'                 => $requested_user_id,
>         'me.active              => 1,
>         'me.date_expires'       => [
>             { '>' => \'now()' },  # past expired
>             { '=' => undef },     # or never expires
>         ],
> 
>         'account.active'        => 1,
>         'account.balance'       => { '>' => 0 },
>         'account.locked'        => 0,
>         'account.date_expires'  => [
>             { '>' => \'now()' },  # past expired
>             { '=' => undef },     # or never expires
>         ],
>     },
>     {
>         join => 'account',
>     },
> );
> 
> [That's not a great example because we assume that "user" and "account"
> might get checked when first logging in.  Ignore that. Just assume a query
> that does a lot of joins to test if a given object can be accessed.]

Am I correct in thinking that's built up in multiple ->search calls?

If so ...
 
> The request either succeeds (200) or fails (404).
> 
> The VAST majority of the time the ID provided will return a row because a
> valid ID was provided by the application itself in the first place.
> 
> But, for a tiny, tiny percent a request might fail.  Then the question is
> *why* did it fail?  What WHERE condition or join failed?

... if you keep all the intermediate resultsets around in the stash or
wherever (or better still refactor to resultset methods and have your
custom resultset class keep the intermediate resultsets around) then it
seems like it should be pretty easy to walk back up the chain making
the extra queries until one returns data - at which point you know the last
step you walked back up is the problem child for this request.

That way you get to only make the extra queries in the failure case, for
minimal extra code - basically taking advantage of DBIx::Class' laziness
coming -and- going :)

-- 
Matt S Trout - Shadowcat Systems - Perl consulting with a commit bit and a clue

http://shadowcat.co.uk/blog/matt-s-trout/   http://twitter.com/shadowcat_mst/

Email me now on mst (at) shadowcat.co.uk and let's chat about how our Catalyst
commercial support, training and consultancy packages could help your team.



More information about the Catalyst mailing list