Skip to content

Commit

Permalink
removed around_exception and around_not_found hooks again
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Jul 5, 2012
1 parent 0c0b83a commit 1f2530d
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 151 deletions.
1 change: 0 additions & 1 deletion Changes
@@ -1,6 +1,5 @@

3.03 2012-07-05
- Added around_exception and around_not_found hooks.
- Improved documentation.
- Improved tests.
- Fixed small namespace detection bug in Mojo::DOM.
Expand Down
108 changes: 2 additions & 106 deletions lib/Mojolicious.pm
Expand Up @@ -3,7 +3,6 @@ use Mojo::Base 'Mojo';

use Carp 'croak';
use Mojo::Exception;
use Mojo::Home;
use Mojolicious::Commands;
use Mojolicious::Controller;
use Mojolicious::Plugins;
Expand Down Expand Up @@ -37,15 +36,6 @@ has types => sub { Mojolicious::Types->new };
our $CODENAME = 'Rainbow';
our $VERSION = '3.03';

# Bundled templates
our $H = Mojo::Home->new;
$H->parse($H->parse($H->mojo_lib_dir)->rel_dir('Mojolicious/templates'));
our $MOJOBAR = $H->slurp_rel_file('mojobar.html.ep');
my $EXCEPTION = $H->slurp_rel_file('exception.html.ep');
my $DEV_EXCEPTION = $H->slurp_rel_file('exception.development.html.ep');
my $NOT_FOUND = $H->slurp_rel_file('not_found.html.ep');
my $DEV_NOT_FOUND = $H->slurp_rel_file('not_found.development.html.ep');

# "These old doomsday devices are dangerously unstable.
# I'll rest easier not knowing where they are."
sub AUTOLOAD {
Expand Down Expand Up @@ -165,16 +155,14 @@ sub handler {
weaken $c->{tx};

# Dispatcher
unless ($self->{started}) {
unless ($self->{dispatch}) {
$self->hook(
around_dispatch => sub {
my ($next, $c) = @_;
$c->app->dispatch($c);
}
);
$self->hook(around_exception => sub { _exception(@_) });
$self->hook(around_not_found => sub { _not_found(@_) });
$self->{started}++;
$self->{dispatch}++;
}

# Process
Expand Down Expand Up @@ -215,63 +203,6 @@ sub start { ($ENV{MOJO_APP} = shift)->commands->start(@_) }

sub startup { }

sub _exception {
my ($next, $c, $e) = @_;

# Filtered stash snapshot
my $stash = $c->stash;
my %snapshot = map { $_ => $stash->{$_} }
grep { !/^mojo\./ and defined $stash->{$_} } keys %$stash;

# Render with fallbacks
my $mode = $c->app->mode;
my $options = {
exception => $e,
snapshot => \%snapshot,
template => "exception.$mode",
format => $stash->{format} || 'html',
handler => undef,
status => 500
};
my $inline = $mode eq 'development' ? $DEV_EXCEPTION : $EXCEPTION;
return if _fallbacks($c, $options, 'exception', $inline);
_fallbacks($c, {%$options, format => 'html'}, 'exception', $inline);
}

sub _fallbacks {
my ($c, $options, $template, $inline) = @_;

# Mode specific template
unless ($c->render($options)) {

# Template
$options->{template} = $template;
unless ($c->render($options)) {

# Inline template
my $stash = $c->stash;
return unless $stash->{format} eq 'html';
delete $stash->{layout};
delete $stash->{extends};
delete $options->{template};
return $c->render(%$options, inline => $inline, handler => 'ep');
}
}
}

sub _not_found {
my ($next, $c) = @_;

# Render with fallbacks
my $mode = $c->app->mode;
my $format = $c->stash->{format} || 'html';
my $options
= {template => "not_found.$mode", format => $format, status => 404};
my $inline = $mode eq 'development' ? $DEV_NOT_FOUND : $NOT_FOUND;
return if _fallbacks($c, $options, 'not_found', $inline);
_fallbacks($c, {%$options, format => 'html'}, 'not_found', $inline);
}

1;

=head1 NAME
Expand Down Expand Up @@ -575,41 +506,6 @@ hook can trigger before C<after_static_dispatch> due to its dynamic nature.
Useful for rewriting outgoing responses and other post-processing tasks.
(Passed the current controller object)
=item C<around_exception>
Emitted when an exception occurs or
L<Mojolicious::Controller/"render_exception"> has been called. The last hook
in the chain will use the renderer to try and find an exception template or
fall back to a built-in one.
$app->hook(around_exception => sub {
my ($next, $c, $e) = @_;
...
$next->();
...
});
Useful for monitoring and generating custom exception responses. (Passed a
closure leading to the next hook, the current controller object and an
exception object)
=item C<around_not_found>
Emitted when the static dispatcher and router didn't handle a request or
L<Mojolicious::Controller/"render_not_found"> has been called. The last hook
in the chain will use the renderer to try and find a not found template or
fall back to a built-in one.
$app->hook(around_not_found => sub {
my ($next, $c) = @_;
...
$next->();
...
});
Useful for monitoring and generating custom fallback responses. (Passed a
closure leading to the next hook and the current controller object)
=item C<around_dispatch>
Emitted right before the C<before_dispatch> hook and wraps around the whole
Expand Down
73 changes: 65 additions & 8 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -5,6 +5,7 @@ use Carp ();
use Mojo::ByteStream;
use Mojo::Cookie::Response;
use Mojo::Exception;
use Mojo::Home;
use Mojo::Transaction::HTTP;
use Mojo::URL;
use Mojo::Util;
Expand All @@ -19,6 +20,15 @@ has match => sub {
};
has tx => sub { Mojo::Transaction::HTTP->new };

# Bundled templates
our $H = Mojo::Home->new;
$H->parse($H->parse($H->mojo_lib_dir)->rel_dir('Mojolicious/templates'));
our $MOJOBAR = $H->slurp_rel_file('mojobar.html.ep');
my $EXCEPTION = $H->slurp_rel_file('exception.html.ep');
my $DEV_EXCEPTION = $H->slurp_rel_file('exception.development.html.ep');
my $NOT_FOUND = $H->slurp_rel_file('not_found.html.ep');
my $DEV_NOT_FOUND = $H->slurp_rel_file('not_found.development.html.ep');

# Reserved stash values
my %RESERVED = map { $_ => 1 } (
qw(action app cb controller data extends format handler json layout),
Expand Down Expand Up @@ -232,9 +242,29 @@ sub render_data { shift->render(data => @_) }
# Neat."
sub render_exception {
my ($self, $e) = @_;

# Log exception
my $app = $self->app;
$app->log->error($e = Mojo::Exception->new($e));
$app->plugins->emit_chain('around_exception', $self, $e);

# Filtered stash snapshot
my $stash = $self->stash;
my %snapshot = map { $_ => $stash->{$_} }
grep { !/^mojo\./ and defined $stash->{$_} } keys %$stash;

# Render with fallbacks
my $mode = $app->mode;
my $options = {
exception => $e,
snapshot => \%snapshot,
template => "exception.$mode",
format => $stash->{format} || 'html',
handler => undef,
status => 500
};
my $inline = $mode eq 'development' ? $DEV_EXCEPTION : $EXCEPTION;
return if $self->_fallbacks($options, 'exception', $inline);
$self->_fallbacks({%$options, format => 'html'}, 'exception', $inline);
}

# "If you hate intolerance and being punched in the face by me,
Expand All @@ -247,7 +277,15 @@ sub render_later { shift->stash->{'mojo.rendered'}++ }
# Lick my frozen metal ass."
sub render_not_found {
my $self = shift;
$self->app->plugins->emit_chain(around_not_found => $self);

# Render with fallbacks
my $mode = $self->app->mode;
my $format = $self->stash->{format} || 'html';
my $options
= {template => "not_found.$mode", format => $format, status => 404};
my $inline = $mode eq 'development' ? $DEV_NOT_FOUND : $NOT_FOUND;
return if $self->_fallbacks($options, 'not_found', $inline);
$self->_fallbacks({%$options, format => 'html'}, 'not_found', $inline);
}

# "You called my thesis a fat sack of barf, and then you stole it?
Expand Down Expand Up @@ -472,6 +510,27 @@ sub write_chunk {
return $self->rendered;
}

sub _fallbacks {
my ($self, $options, $template, $inline) = @_;

# Mode specific template
unless ($self->render($options)) {

# Template
$options->{template} = $template;
unless ($self->render($options)) {

# Inline template
my $stash = $self->stash;
return unless $stash->{format} eq 'html';
delete $stash->{layout};
delete $stash->{extends};
delete $options->{template};
return $self->render(%$options, inline => $inline, handler => 'ep');
}
}
}

1;

=head1 NAME
Expand Down Expand Up @@ -672,9 +731,8 @@ not be encoded. All additional values get merged into the C<stash>.
$c->render_exception('Oops!');
$c->render_exception(Mojo::Exception->new('Oops!'));
Emit C<around_exception> plugin hook, render the exception template
C<exception.$mode.$format.*> or C<exception.$format.*> and set the response
status code to C<500>.
Render the exception template C<exception.$mode.$format.*> or
C<exception.$format.*> and set the response status code to C<500>.
=head2 C<render_json>
Expand Down Expand Up @@ -704,9 +762,8 @@ useful.
$c->render_not_found;
Emit C<around_not_found> plugin hook, render the not found template
C<not_found.$mode.$format.*> or C<not_found.$format.*> and set the response
status code to C<404>.
Render the not found template C<not_found.$mode.$format.*> or
C<not_found.$format.*> and set the response status code to C<404>.
=head2 C<render_partial>
Expand Down
6 changes: 3 additions & 3 deletions lib/Mojolicious/Guides/Rendering.pod
Expand Up @@ -358,11 +358,11 @@ production. The renderer will always try to find C<exception.$mode.$format.*>
or C<not_found.$mode.$format.*> before falling back to the built-in default
templates.

@@ not_found.production.html.ep
@@ exception.production.html.ep
<!DOCTYPE html>
<html>
<head><title>Page not found</title></head>
<body>Page does not seem to exist.</body>
<head><title>Server error</title></head>
<body><%= $exception %></body>
</html>

=head2 Helpers
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/Plugin/PODRenderer.pm
Expand Up @@ -12,7 +12,7 @@ use Pod::Simple::Search;
my @PATHS = map { $_, "$_/pods" } @INC;

# Bundled files
my $PERLDOC = $Mojolicious::H->slurp_rel_file('perldoc.html.ep');
my $PERLDOC = $Mojolicious::Controller::H->slurp_rel_file('perldoc.html.ep');

# "This is my first visit to the Galaxy of Terror and I'd like it to be a
# pleasant one."
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/templates/exception.development.html.ep
Expand Up @@ -98,7 +98,7 @@
% end
</head>
<body onload="prettyPrint()">
%= include inline => $Mojolicious::MOJOBAR
%= include inline => $Mojolicious::Controller::MOJOBAR
<div id="wrapperlicious">
<div id="nothing" class="box spaced"></div>
% my $cv = begin
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/templates/not_found.development.html.ep
Expand Up @@ -74,7 +74,7 @@
% end
</head>
<body onload="prettyPrint()">
%= include inline => $Mojolicious::MOJOBAR
%= include inline => $Mojolicious::Controller::MOJOBAR
<div id="wrapperlicious">
<div id="routes">
<h1>Page not found... yet!</h1>
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/templates/perldoc.html.ep
Expand Up @@ -61,7 +61,7 @@
% end
</head>
<body onload="prettyPrint()">
%= include inline => $Mojolicious::MOJOBAR
%= include inline => $Mojolicious::Controller::MOJOBAR
% my $link = begin
%= link_to shift, shift, class => "mojoscroll"
% end
Expand Down

0 comments on commit 1f2530d

Please sign in to comment.