[Maypole-dev] Maypole & error handling

From: Simon Flack (sf at flacks.net)
Date: Tue Sep 14 2004 - 20:46:19 BST


I've read the section on error handling in the request cookbook, but I'd like
to do something a bit more advanced with exception objects, and I'd like to
let my model classes try and handle exceptions too.

It's possible to achieve some of this by overriding &process in your model
class, but it's not easy or straightforward to handle exceptions at the
application level. Here's a contrived example of the sort of thing I'd like to
be able to do:

package My::Controller;
use base 'Apache::MVC;
use Maypole::Constants;

use Exception::Class
    E::FAIL => {description => 'Application error'},
    E::ACCESS_DENIED => {description => 'insufficient permissions'},
    E::INVALIDARGS => {description => 'Missing or invalid arguments',
                       fields => 'parameter'};

# ...

sub error_handler {
    my ($r, $error) = @_;

    return ERROR unless ref $error;
    if (UNIVERSAL::isa($error, E::ACCESS_DEINED) {
       # log invalid request...
       $r->template('access_denied');
       return OK;
    } elsif (UNIVERSAL::isa($error, E::FAIL) {
       $r->template('general_failure');
       return OK;
    }
    return ERROR:
}

#----------------------------------------------
package My::Model;
use Maypole::Constants;

sub error_handler {
    my $class = shift;
    my ($r, $error) = @_;

    # Just handle E_INVALIDARGS here, let controller deal
    # with everything else
    if (UNIVERSAL::isa($error, 'E::INVALIDARGS') {
        return $r->error('Invalid value for ' . $error->parameter);
    }
    return ERROR;
}

sub view :Exported {
    my ($class, $r) = @_;

    my $item = $r->{objects}[0];
    throw E::FAIL ('The requested resource has expired')
        if $item->expired;
    throw E::ACCESS_DENIED ('You do not have permission to access this
resource')
        unless $r->{user}->access_level >= $item->access_level;
    throw E::INVALIDARGS (parameter => 'key')
        unless $r->param('key') =~ /^[A-F0-9]{6}$/;
}

I've attached a small patch to Maypole.pm that should make this work. If your
model raises an exception, Maypole will first try and call an 'error_handler'
method in your model class. If that doesn't exist or returns anything other
than OK, the 'error_handler' method on the application class will be given the
chance to handle the exception. If that doesn't exist or returns anything
other than OK, the current default behaviour will kick in.

--simonflk



_______________________________________________
maypole-dev mailing list
maypole-dev at lists.netthink.co.uk
http://lists.netthink.co.uk/listinfo/maypole-dev



This archive was generated by hypermail 2.1.3 : Thu Feb 24 2005 - 22:25:56 GMT