Skip to content

Commit

Permalink
merged exception and not found pages
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Feb 11, 2014
1 parent f6b2ed2 commit c9392e1
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 249 deletions.
3 changes: 2 additions & 1 deletion Changes
@@ -1,6 +1,7 @@

4.79 2014-02-11
- Improved not found page to show the exact path used for route matching.
- Improved not found page to show request information and the exact path
used for route matching.

4.78 2014-02-08
- Deprecated Mojo::Util::get_line.
Expand Down
79 changes: 34 additions & 45 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -172,55 +172,13 @@ sub render {
return !!$self->rendered($self->stash->{status});
}

sub render_exception {
my ($self, $e) = @_;

my $app = $self->app;
$app->log->error($e = Mojo::Exception->new($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 $renderer = $app->renderer;
my $options = {
exception => $e,
snapshot => \%snapshot,
template => "exception.$mode",
format => $stash->{format} || $renderer->default_format,
handler => undef,
status => 500
};
my $inline = $renderer->_bundled(
$mode eq 'development' ? 'exception.development' : 'exception');
return $self if _fallbacks($self, $options, 'exception', $inline);
_fallbacks($self, {%$options, format => 'html'}, 'exception', $inline);
return $self;
}
sub render_exception { _development('exception', @_) }

sub render_later { shift->stash('mojo.rendered' => 1) }

sub render_maybe { shift->render(@_, 'mojo.maybe' => 1) }

sub render_not_found {
my $self = shift;

# Render with fallbacks
my $app = $self->app;
my $mode = $app->mode;
my $renderer = $app->renderer;
my $format = $self->stash->{format} || $renderer->default_format;
my $options
= {template => "not_found.$mode", format => $format, status => 404};
my $inline = $renderer->_bundled(
$mode eq 'development' ? 'not_found.development' : 'not_found');
return $self if _fallbacks($self, $options, 'not_found', $inline);
_fallbacks($self, {%$options, format => 'html'}, 'not_found', $inline);
return $self;
}
sub render_not_found { _development('not_found', @_) }

sub render_static {
my ($self, $file) = @_;
Expand Down Expand Up @@ -440,6 +398,35 @@ sub write_chunk {
return $self->rendered;
}

sub _development {
my ($page, $self, $e) = @_;

my $app = $self->app;
$app->log->error($e = Mojo::Exception->new($e)) if $page eq 'exception';

# 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 $renderer = $app->renderer;
my $options = {
snapshot => \%snapshot,
template => "$page.$mode",
format => $stash->{format} || $renderer->default_format,
handler => undef,
status => $page eq 'exception' ? 500 : 404
};
$options->{exception} = $e if $page eq 'exception';
my $inline
= $renderer->_bundled($mode eq 'development' ? 'development' : $page);
return $self if _fallbacks($self, $options, $page, $inline);
_fallbacks($self, {%$options, format => 'html'}, $page, $inline);
return $self;
}

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

Expand Down Expand Up @@ -746,7 +733,9 @@ could be generated, takes the same arguments as L</"render">.
$c = $c->render_not_found;
Render the not found template C<not_found.$mode.$format.*> or
C<not_found.$format.*> and set the response status code to C<404>.
C<not_found.$format.*> and set the response status code to C<404>. Also sets
the stash value C<snapshot> to a copy of the L</"stash"> for use in the
templates.
=head2 render_static
Expand Down
@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>Server error (<%= app->mode %> mode)</title>
% my $title = stash('exception') ? 'Server error' : 'Page not found';
<title><%= $title %> (<%= app->mode %> mode)</title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
%= javascript '/mojo/jquery/jquery.js'
Expand All @@ -17,6 +18,19 @@
line-height: 1.5em;
margin: 0;
}
code {
background-color: #eef9ff;
border: solid #cce4ff 1px;
border-radius: 5px;
color: #333;
font: 0.9em Consolas, Menlo, Monaco, Courier, monospace;
padding: 0.4em;
}
h1 {
color: #2a2a2a;
font-size: 1.5em;
margin: 0;
}
pre {
font: 0.9em Consolas, Menlo, Monaco, Courier, monospace;
margin: 0;
Expand Down Expand Up @@ -54,10 +68,8 @@
font: 0.5em Verdana, sans-serif;
text-align: center;
}
.value {
padding-left: 1em;
width: 100%;
}
.value { padding-left: 1em }
.wide { width: 100% }
#footer {
padding-top: 1em;
text-align: center;
Expand Down Expand Up @@ -90,6 +102,11 @@
border-top-right-radius: 5px;
margin-top: 1em;
}
#routes {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
padding-top: 70px;
}
#wrapperlicious {
max-width: 1000px;
margin: 0 auto;
Expand All @@ -114,82 +131,127 @@
});
% end
<div id="wrapperlicious">
<div id="nothing" class="box spaced"></div>
% my $cv = begin
% my ($key, $value, $i) = @_;
%= tag 'tr', $i ? (class => 'important') : undef, begin
<td class="key"><%= $key %></td>
<td class="value"><pre class="prettyprint"><%= $value %></pre></td>
% end
% end
% my $kv = begin
% my ($key, $value) = @_;
<tr>
<td class="key"><%= $key %>:</td>
<td class="striped value"><pre><%= $value %></pre></td>
<td class="striped value wide"><pre><%= $value %></pre></td>
</tr>
% end
<div id="showcase" class="box code spaced">
<pre><%= $exception->message %></pre>
<div id="context" class="more">
<table>
% for my $line (@{$exception->lines_before}) {
%= $cv->($line->[0], $line->[1])
% }
% if (defined $exception->line->[1]) {
%= $cv->($exception->line->[0], $exception->line->[1], 1)
% }
% for my $line (@{$exception->lines_after}) {
%= $cv->($line->[0], $line->[1])
% }
</table>
</div>
% if (defined $exception->line->[2]) {
<div id="insight" class="more">
% if (my $exception = stash 'exception') {
<div id="nothing" class="box spaced"></div>
% my $cv = begin
% my ($key, $value, $i) = @_;
%= tag 'tr', $i ? (class => 'important') : undef, begin
<td class="key"><%= $key %></td>
<td class="value wide">
<pre class="prettyprint"><%= $value %></pre>
</td>
% end
% end
<div id="showcase" class="box code spaced">
<pre><%= $exception->message %></pre>
<div id="context" class="more">
<table>
% for my $line (@{$exception->lines_before}) {
%= $cv->($line->[0], $line->[2])
%= $cv->($line->[0], $line->[1])
% }
% if (defined $exception->line->[1]) {
%= $cv->($exception->line->[0], $exception->line->[1], 1)
% }
%= $cv->($exception->line->[0], $exception->line->[2], 1)
% for my $line (@{$exception->lines_after}) {
%= $cv->($line->[0], $line->[2])
%= $cv->($line->[0], $line->[1])
% }
</table>
</div>
<div class="tap">tap for more</div>
%= javascript begin
var current = '#context';
$('#showcase').click(function() {
$(current).slideToggle('slow', function() {
if (current == '#context') {
current = '#insight';
}
else {
current = '#context';
}
$(current).slideToggle('slow');
% if (defined $exception->line->[2]) {
<div id="insight" class="more">
<table>
% for my $line (@{$exception->lines_before}) {
%= $cv->($line->[0], $line->[2])
% }
%= $cv->($exception->line->[0], $exception->line->[2], 1)
% for my $line (@{$exception->lines_after}) {
%= $cv->($line->[0], $line->[2])
% }
</table>
</div>
<div class="tap">tap for more</div>
%= javascript begin
var current = '#context';
$('#showcase').click(function() {
$(current).slideToggle('slow', function() {
if (current == '#context') {
current = '#insight';
}
else {
current = '#context';
}
$(current).slideToggle('slow');
});
});
});
$('#insight').toggle();
$('#insight').toggle();
% end
% }
</div>
<div id="trace" class="box spaced">
% if (@{$exception->frames}) {
<div id="frames" class="infobox more">
<table>
% for my $frame (@{$exception->frames}) {
<tr>
<td class="striped value wide">
<pre><%= $frame->[1] . ':' . $frame->[2] %></pre>
</td>
</tr>
% }
</table>
</div>
<div class="tap">tap for more</div>
% }
</div>
% }
% else {
<div id="routes" class="box infobox spaced">
<h1>Page not found... yet!</h1>
<p>
None of these routes could generate a response for your
<code><%= $self->req->method %></code> request for
<code><%= $self->req->url->path->to_route %></code>, maybe you need
to add a new one?
</p>
% my $walk = begin
% my ($walk, $route, $depth) = @_;
<tr>
<td class="striped value">
% my $pattern = $route->pattern->pattern || '/';
% $pattern = "+$pattern" if $depth;
<pre><%= ' ' x $depth %><%= $pattern %></pre>
</td>
<td class="striped value">
<pre><%= uc(join ',', @{$route->via || []}) || '*' %></pre>
</td>
<td class="striped value">
% my $name = $route->name;
<pre><%= $route->has_custom_name ? qq{"$name"} : $name %></pre>
</td>
</tr>
% $depth++;
%= $walk->($walk, $_, $depth) for @{$route->children};
% $depth--;
% end
% }
</div>
<div id="trace" class="box spaced">
% if (@{$exception->frames}) {
<div id="frames" class="infobox more">
<table>
% for my $frame (@{$exception->frames}) {
<tr>
<td class="striped value">
<pre><%= $frame->[1] . ':' . $frame->[2] %></pre>
</td>
</tr>
% }
</table>
</div>
<div class="tap">tap for more</div>
% }
</div>
<table>
<thead>
<tr>
<th>Pattern</th>
<th>Methods</th>
<th>Name</th>
</tr>
</thead>
%= $walk->($walk, $_, 0) for @{app->routes->children};
</table>
</div>
% }
<div id="request" class="box infobox spaced">
<table>
% my $req = $self->req;
Expand Down Expand Up @@ -238,7 +300,7 @@
% $time = localtime $time;
% my $lines = join "\n", @lines;
<tr>
<td class="striped value">
<td class="striped value wide">
<pre>[<%= $time %>] [<%= $level %>] <%= $lines %></pre>
</td>
</tr>
Expand Down

0 comments on commit c9392e1

Please sign in to comment.