CatalystX-Errors/lib/Catalyst/ActionRole/RenderErrors.pm
package Catalyst::ActionRole::RenderErrors;
use Moose::Role;
my $dont_dispatch_error = sub {
my ($self, $controller, $c) = @_;
return 1 if $c->req->method eq 'HEAD';
return 1 if defined $c->response->body;
return 1 if $c->response->status =~ /^(?:204|3\d\d)$/;
return 0;
};
around 'execute', sub {
my ($orig, $self, $controller, $c, @args) = @_;
my $ret = $self->$orig($controller, $c, @args);
return $ret if $self->$dont_dispatch_error($controller, $c);
my @errors = @{$c->error};
return $ret unless @errors;
my $first = $errors[-1]; # We can only handle the last error in the stack
if($c->looks_like_http_error_obj($first)) {
my ($status_code, $additional_headers, $template_args) = $first->as_http_response;
$c->clear_errors && $c->dispatch_error($status_code, $additional_headers, $template_args)
unless ($c->debug && ($status_code >= 500));
} else {
$c->log->error($first);
$c->clear_errors && $c->dispatch_error(500) unless $c->debug;
}
return $ret;
};
1;
=head1 NAME
Catalyst::ActionRole::RenderErrors - Automatically return an error page
=head1 SYNOPSIS
package Example::Controller::Root;
use Moose;
use MooseX::MethodAttributes;
extends 'Catalyst::Controller';
sub root :Chained(/) PathPart('') CaptureArgs(0) {}
sub not_found :Chained(root) PathPart('') Args {
my ($self, $c, @args) = @_;
$c->detach_error(404);
}
sub die :Chained(root) PathPart(die) Args(0) {
die "saefdsdfsfs";
}
sub end :Does(RenderErrors) { }
__PACKAGE__->config(namespace=>'');
__PACKAGE__->meta->make_immutable;
=head1 DESCRIPTION
Tries to convert the last error in '$c->error' to something we can dispatch an error view too.
If the first error in '$c->error' is an object that looks like it does L<CatalystX::Utils::DoesHttpException>
then we use that error to get the HTTP status code and any additional arguments. If its not then we just return
a simple HTTP 500 Bad request. In that case we won't return any information in C<$c->error> since that might leak
sensitiver Perl debugging info. A stringified version of the error is sent to the error log.
Useful for API work since the default L<Catalyst> error page is in HTML and if your client is requesting
JSON we'll return a properly formatted response in C<application/json>.
B<NOTE> if you are in CATALYST_DEBUG mode then all HTTP 500 errors and non specific errors will still
dump the development debugging error screen.
=head1 SEE ALSO
L<CatalystX::Errors>.
=head1 AUTHOR
L<CatalystX::Errors>.
=head1 COPYRIGHT & LICENSE
L<CatalystX::Errors>.
=cut