Apache2-Controller

 view release on metacpan or  search on metacpan

lib/Apache2/Controller.pm  view on Meta::CPAN

which gets you to all the RequestRec, RequestUtil,
RequestIO methods etc.

The rest of this manual assumes that you do use
L<Apache2::Request> as a base in your controller,
and refers to its methods via C<< $self >>.  Just
keep in mind that you don't have to, but can
access those methods via C<< $self->{r} >>.

=head1 RETURN VALUES

Your controller methods should use C<< eval { } >> if necessary and
act accordingly, set the right things for C<Apache2::RequestRec> 
and return the right HTTP constant.  See L<Apache2::Const/:http>
and L<Apache2::Controller::Refcard>.

In the event of an error, if you wish, use L<Apache2::Controller::X>
and throw one with field 'status' set to a valid HTTP return code.  
This lets you implement nice error templates if your controller uses 
L<Apache2::Controller::Render::Template> as a base.
See L<ERRORS> below.

Success in the controller method normally should just return the
appropriate HTTP status code.  You can return HTTP_OK (200) if that
is what you mean, or it is the default status if you return OK (0).

Or, if you do C<< $self->status( Apache2::Const::HTTP_SOMETHING ) >>
and then just C<< return() >>
or return OK (0), Apache2::Controller will not override the set status.

See L<Apache2::Controller::Refcard> for a list of HTTP return constants
and corresponding numbers and messages.

=head2 REDIRECTS, ETC.

As an example of return values, take browser redirects.
There's no need for an abstraction mechanism around redirects
since you have direct access to the Apache methods.

 package MyApp::Controller::Somewhere;
 use base qw( Apache2::Controller Apache2::Request );
 use Apache2::Const -compile => qw( REDIRECT );

 # maybe dispatched from http://myapp.xyz/somewhere/go_elsewhere
 sub go_elsewhere {
     my ($self, @path_args) = @_;
     $self->err_headers_out->add(Location => 'http://foo.bar');
     return Apache2::Const::REDIRECT;
 }

Keep in mind that if you use other request phase processors that
push a C<PerlLogHandler> like 
L<Apache2::Controller::DBI::Connector> or
L<Apache2::Controller::Session>, those will still run,
but for example the session controller won't save the session
if you set or return an http status higher than the HTTP_OK family
(HTTP_MULTIPLE_CHOICES (300) or higher.)

You should also not fiddle with the connection by causing
Apache2 to close it prematurely, else the post-response handlers 
may not run or won't run synchronously before another request 
is received that may have depended on their behavior.
(For example, you can't use a C<< PerlCleanupHandler >>
to do things like that because the request has already closed,
and it doesn't get processed before taking in the next request,
even when running in single-process mode.)

=head1 ERRORS

If you decide to set an error status code, you can print your
own content and return that status code.

If you want to use error templates, 
barf L<Apache2::Controller::X> objects.  These print a stack trace
to the error log at the WARN level of L<Log::Log4perl> from
this module's namespace.  If errors crop up from
other A2C request phase handlers, try setting
WARN log level for L<Apache2::Controller::NonResponseBase>
or L<Apache2::Controller::NonResponseRequest>.

Also see L<Apache2::Controller::Render::Template>.

You can use or subclass L<Apache2::Controller::X>,
to use C<< a2cx() >>,
or you can throw your own exception objects,
or just C<< die() >>, or C<< croak() >>,
or set C<< $self->status >>, headers etc., possibly printing content, 
or return the appropriate status from your controller method.

See L<Apache2::Controller::X> for help on throwing exceptions
with HTTP status, data dumps, etc.

If your code does break, die or throw an exception, this is 
caught by Apache2::Controller.  If your controller module implements
an C<<error() >> method, 
then C<< $handler->error() >> will be called passing the C<< $EVAL_ERROR >>
or exception object as the first argument.

 package MyApp::C::Foo;
 use YAML::Syck;
 # ...
 sub error {
     my ($self, $X) = @_;
     $self->status( Apache2::Const::HTTP_BAD_REQUEST );
     $self->content_type('text/plain');
     $self->print("Take this job and shove it!\n", "\n", $X, "\n");
     if ($X->isa('Apache2::Controller::X')) {
        # usually you wouldn't show gory details to the user...
        $self->print(Dump($X->dump)) if $X->dump;
        $self->print($X->trace) if $X->trace;  
     }
 }

For instance 
L<Apache2::Controller::Render::Template> implements
C<< error() >> for you, which looks for
the appropriately named error template as
F<template_dir/errors/###.html>.

Of course, all exceptions are sent to the error log using
L<Log::Log4perl> DEBUG() before the handler completes, and



( run in 0.413 second using v1.01-cache-2.11-cpan-e1769b4cff6 )