Mojolicious模板渲染(七)

一、渲染异常页和not_found页

任何一个网站,都要有404页面和500页面。当我们的网站犯错时,会自动的抛出异常页面。当我们的异常处理失败时,这些页面将作为后备方案,这在开发过程中特别有用。我们可以使用Mojolicious::Plugin::DefaultHelpers模块中的reply->exception和reply->not_found:

use Mojolicious::Lite -signatures;
use Scalar::Util qw(looks_like_number);

get '/divide/:dividend/by/:divisor' => sub ($c) {

  my $dividend = $c->param('dividend');
  my $divisor  = $c->param('divisor');

  # 404
  return $c->reply->not_found
    unless looks_like_number $dividend && looks_like_number $divisor;

  # 500
  return $c->reply->exception('Division by zero!') if $divisor == 0;

  # 200
  $c->render(text => $dividend / $divisor);
};

app->start;

如果希望向用户展示与生产应用程序更密切相关的内容,我们还可以更改这些页面的模板。在退回到内置默认模板之前,渲染器总是会试图找到exception.$mode.$format.*或not_found.$mode.$format.*.

use Mojolicious::Lite;

get '/dies' => sub { die 'Intentional error' };

app->start;
__DATA__

@@ exception.production.html.ep
 #对应exception.$mode.$format.*
<!DOCTYPE html>
<html>
  <head><title>Server error</title></head>
  <body>
    <h1>Exception</h1>
    <p><%= $exception->message %></p>
    <h1>Stash</h1>
    <pre><%= dumper $snapshot %></pre>
  </body>
</html>

Mojolicious中的“before_render”钩子允许你拦截和修改传递给渲染器的参数,从而实现了更高级的定制。

use Mojolicious::Lite -signatures;

hook before_render => sub ($c, $args) {

  # 确认将要渲染的是异常模板
  return unless my $template = $args->{template};
  return unless $template eq 'exception';

  # 如果内容协商中的accepts为json格式,则返回一个json格式的异常。
  return unless $c->accepts('json');
  $args->{json} = {exception => $c->stash('exception')};
};

get '/' => sub { die "This sho...ALL GLORY TO THE HYPNOTOAD!\n" };

app->start;

标签