[Jifty-commit] r6311 - in jifty/trunk: . lib/Jifty lib/Jifty/Plugin lib/Jifty/Plugin/ErrorTemplates lib/Jifty/View/Declare lib/Jifty/View/Mason plugins.old/EmailErrors/lib/Jifty/Plugin/EmailErrors share/web/templates t/TestApp/lib/TestApp t/TestApp/share/web/templates
Jifty commits
jifty-commit at lists.jifty.org
Thu Feb 5 14:02:13 EST 2009
Author: alexmv
Date: Thu Feb 5 14:02:12 2009
New Revision: 6311
Added:
jifty/trunk/t/TestApp/share/web/templates/call-region-with-error
jifty/trunk/t/TestApp/share/web/templates/region-with-error
Removed:
jifty/trunk/share/web/templates/dhandler
Modified:
jifty/trunk/ (props changed)
jifty/trunk/lib/Jifty/Dispatcher.pm
jifty/trunk/lib/Jifty/Plugin/ErrorTemplates.pm
jifty/trunk/lib/Jifty/Plugin/ErrorTemplates/View.pm
jifty/trunk/lib/Jifty/View/Declare/Handler.pm
jifty/trunk/lib/Jifty/View/Mason/Handler.pm
jifty/trunk/lib/Jifty/View/Mason/Request.pm
jifty/trunk/lib/Jifty/Web.pm
jifty/trunk/plugins.old/EmailErrors/lib/Jifty/Plugin/EmailErrors/Dispatcher.pm
jifty/trunk/t/TestApp/etc/config.yml
jifty/trunk/t/TestApp/lib/TestApp/View.pm
jifty/trunk/t/TestApp/share/web/templates/template-with-error
Log:
r41872 at kohr-ah: chmrr | 2009-02-05 14:01:22 -0500
* Rework error handling. Mason's dhandler is no longer in charge of
generating 404's; instead, the dispatcher catches when no views can
handle a request.
* Relatedly, don't bother catching, popping the buffer stack, and
rethrowing on every error. Instead, explicitly _don't_ pop the
stack, and use the frames that remain on the stack when we catch it
in the dispatcher to show a stack trace.
* Rename 'mason_internal_error' to the more straightforward
'/errors/500', and have ErrorTemplates do the right thing.
Modified: jifty/trunk/lib/Jifty/Dispatcher.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Dispatcher.pm (original)
+++ jifty/trunk/lib/Jifty/Dispatcher.pm Thu Feb 5 14:02:12 2009
@@ -772,6 +772,8 @@
=cut
+my %TEMPLATE_CACHE;
+
sub _do_show {
my $self = shift;
my $path;
@@ -791,22 +793,27 @@
# a relative path, prepend the working directory
$path = "$self->{cwd}/$path" unless $path =~ m{^/};
- # When we're requesting a directory, go looking for the index.html if the
- # path given does not exist
- if ( ! $self->template_exists( $path )
- && $self->template_exists( $path . "/index.html" ) ) {
- $path .= "/index.html";
- }
-
+ # Check for ../../../../../etc/passwd
my $abs_template_path = Jifty::Util->absolute_path( Jifty->config->framework('Web')->{'TemplateRoot'} . $path );
my $abs_root_path = Jifty::Util->absolute_path( Jifty->config->framework('Web')->{'TemplateRoot'} );
+ $self->render_template('/errors/500')
+ if $abs_template_path !~ /^\Q$abs_root_path\E/;
- if ( $abs_template_path !~ /^\Q$abs_root_path\E/ ) {
- $self->render_template('/__jifty/errors/500');
- } else {
- $self->render_template( $path);
+ # When we're requesting a directory, go looking for the index.html if the
+ # path given does not exist. Cache the handler and path.
+ if ( not exists $TEMPLATE_CACHE{$path} or Jifty->config->framework('DevelMode')) {
+ my $handler;
+ if ( $handler = $self->template_exists( $path ) ) {
+ $TEMPLATE_CACHE{$path} = [ $path, $handler ];
+ } elsif ( $handler = $self->template_exists( $path . "/index.html" ) ) {
+ $TEMPLATE_CACHE{$path} = [ $path . "/index.html", $handler ];
+ } else {
+ $TEMPLATE_CACHE{$path} = [];
+ }
}
+ $self->render_template( @{$TEMPLATE_CACHE{$path} } );
+
last_rule;
}
@@ -1189,8 +1196,10 @@
=head2 template_exists PATH
-Returns true if PATH is a valid template inside your template root. This checks
-for both Template::Declare and HTML::Mason Templates.
+Returns true if PATH is a valid template inside your template
+root. This checks for both Template::Declare and HTML::Mason
+Templates. Specifically, returns a reference to the handler which can
+process the template.
=cut
@@ -1200,49 +1209,63 @@
foreach my $handler ( Jifty->handler->view_handlers) {
if ( Jifty->handler->view($handler)->template_exists($template) ) {
- return 1;
+ return Jifty->handler->view($handler);
}
}
return undef;
}
-=head2 render_template PATH
+=head2 render_template PATH, [HANDLER]
-Use our templating system to render a template. If there's an error, do the
-right thing. If the same 'PATH' is found in both Template::Declare and
-HTML::Mason templates then the T::D template is used.
+Use our templating system to render a template. If C<HANDLER> is
+provided, uses it to render the template. Otherwise, searches through
+L<Jifty::Handler/view_handlers> to find the first handler which
+provides the given template.
+Catches errors, and redirects to C</errors/500>; also shows
+C</errors/404> if the template cannot be found.
=cut
sub render_template {
my $self = shift;
my $template = shift;
+ my $handler = shift;
my $showed = 0;
+
+ my $start_depth = Jifty->handler->buffer->depth;
eval {
- foreach my $handler ( Jifty->handler->view_handlers ) {
- my $handler_class = Jifty->handler->view($handler);
- if ( $handler_class->template_exists($template) ) {
+ if ($handler) {
+ $handler->show($template);
+ $showed = 1;
+ } elsif (defined $template) {
+ my @handlers = map {Jifty->handler->view($_)} Jifty->handler->view_handlers;
+ push @handlers, Jifty->handler->fallback_view_handler;
+ foreach my $handler_class ( @handlers ) {
+ next unless $handler_class->template_exists($template);
$handler_class->show($template);
$showed = 1;
last;
}
}
- if ( not $showed and my $fallback_handler = Jifty->handler->fallback_view_handler ) {
- $fallback_handler->show($template);
- }
};
- my $err = $@;
# Handle parse errors
- $self->log->fatal("view class error: $err") if $err;
+ my $err = $@;
+ $self->log->fatal("View error: $err") if $err;
if ( $err and not eval { $err->isa('HTML::Mason::Exception::Abort') } ) {
- if ($template eq '/__jifty/error/mason_internal_error') {
- $self->log->debug("can't render internal_error: $err");
+ if ($template eq '/errors/500') {
+ $self->log->warn("Can't render internal_error: $err");
+ # XXX Built-in static "oh noes" page?
$self->_abort;
return;
}
+
+ # XXX: This may leave a half-written tag open
+ $err->template_stack;
+ Jifty->handler->buffer->pop while Jifty->handler->buffer->depth > $start_depth;
+
# Save the request away, and redirect to an error page
Jifty->web->response->error($err);
my $c = Jifty::Continuation->new(
@@ -1250,12 +1273,19 @@
response => Jifty->web->response,
parent => Jifty->web->request->continuation,
);
-
# Redirect with a continuation
- Jifty->web->_redirect( "/__jifty/error/mason_internal_error?J:C=" . $c->id );
+ Jifty->web->_redirect( "/errors/500?J:C=" . $c->id );
} elsif ($err) {
+ Jifty->handler->buffer->pop while Jifty->handler->buffer->depth > $start_depth;
die $err;
}
+
+ # Handle 404's
+ unless ($showed) {
+ return $self->render_template("/errors/404") unless defined $template and $template eq "/errors/404";
+ $self->log->warn("Can't find 404 page!");
+ $self->_abort;
+ }
}
Modified: jifty/trunk/lib/Jifty/Plugin/ErrorTemplates.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/ErrorTemplates.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/ErrorTemplates.pm Thu Feb 5 14:02:12 2009
@@ -4,16 +4,13 @@
package Jifty::Plugin::ErrorTemplates;
use base qw/Jifty::Plugin/;
-# Your plugin goes here. If takes any configuration or arguments, you
-# probably want to override L<Jifty::Plugin/init>.
-
=head1 NAME
Jifty::Plugin::ErrorTemplates - Plugin for showing errors
=head1 DESCRIPTION
-This plugin provides superusers with online documentation for Jifty and your application's API. It's included by default when using Jifty. (That's a bug).
+This plugin provides default error templates for your application.
=cut
Modified: jifty/trunk/lib/Jifty/Plugin/ErrorTemplates/View.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/ErrorTemplates/View.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/ErrorTemplates/View.pm Thu Feb 5 14:02:12 2009
@@ -14,22 +14,22 @@
=head1 DESCRIPTION
-This class is a stub. It's not in use yet. It should be, but that would require mason libraries to be able to call Template::Declare libraries
+Default error templates
=cut
-template '__jifty/error/_elements/error_text' => sub {
+template '/error/_elements/error_text' => sub {
my ($error) = get(qw(error));
h1 { 'Sorry, something went awry' };
p {
_(
-"For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is :"
+"For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is:"
);
};
blockquote {
- b { $error };
+ b { $error || "Internal server error" };
};
p {
@@ -71,45 +71,15 @@
};
}
body {
- div {
- attr { id => 'headers' };
- h1 {'Internal Error'};
- div {
- attr { id => 'content' };
- a { attr { name => 'content' } };
- if ( Jifty->config->framework('AdminMode') ) {
- div {
- attr { class => "warning admin_mode" };
- outs(
- 'Alert:'
- . tangent(
- label => 'administration mode',
- url => '/__jifty/admin/'
- )
- . 'is enabled.'
- );
- }
- }
- Jifty->web->render_messages;
- $code->();
- }
-
- }
+ h1 {'Internal Error'};
+ Jifty->web->render_messages;
+ $code->();
}
}
}
}
-template '__jifty/error/dhandler' => sub {
- my $error = get('error');
- Jifty->log->error( "Unhandled web error " . $error );
- page {
- title is 'Something went awry';
- show( '/__jifty/error/_elements/error_text', error => $error );
- };
-};
-
template '__jifty/error/error.css' => sub {
Jifty->handler->apache->content_type("text/css");
h1 {
@@ -117,13 +87,27 @@
};
};
+sub maybe_page (&;$) {
+ unshift @_, undef unless @_ == 2;
+ my ($meta, $code) = @_;
+ my $ret = sub {
+ if (Jifty->web->request->is_subrequest) {
+ local *is::title = sub {};
+ $code->();
+ } else {
+ page {$meta ? $meta->() : () } content {$code->()};
+ }
+ };
+ $ret->() unless defined wantarray;
+ return $ret;
+}
template '/errors/404' => sub {
- my $file = get('path');
+ my $file = get('path') || Jifty->web->request->path;
Jifty->log->error( "404: user tried to get to " . $file );
- Jifty->handler->apache->header_out( Status => '404' );
- with( title => _("Something's not quite right") ), page {
-
+ Jifty->handler->apache->header_out( Status => '404' )
+ unless Jifty->web->request->is_subrequest;
+ maybe_page { title => _("Something's not quite right") } content {
with( id => "overview" ), div {
p {
join( " ",
@@ -145,42 +129,30 @@
-template '__jifty/error/mason_internal_error' => page {
- { title is _('Something went awry') }
-
+template '/errors/500' => maybe_page { title => _('Something went awry') } content {
my $cont = Jifty->web->request->continuation;
-#my $wrapper = "/__jifty/error/_elements/wrapper" if $cont and $cont->request->path eq "/__jifty/error/mason_internal_error";
-
# If we're not in devel, bail
if ( not Jifty->config->framework("DevelMode") or not $cont ) {
- show("/__jifty/error/_elements/error_text");
-
- # return;
+ show("/error/_elements/error_text");
+ return;
}
+
my $e = $cont->response->error;
if ( ref($e) ) {
my $msg = $e->message;
$msg =~ s/, <\S+> (line|chunk) \d+\././;
- my $info = $e->analyze_error;
- my $file = $info->{file};
- my @lines = @{ $info->{lines} };
- my @stack = @{ $info->{frames} };
-
- outs('Error in ');
- _error_line( $file, "@lines" );
pre {$msg};
- form_return( label => _("Try again") );
+ form {
+ form_return( label => _("Try again") );
+ };
h2 {'Call stack'};
ul {
- for my $frame (@stack) {
- next if $frame->filename =~ m{/HTML/Mason/};
- li {
- _error_line( $frame->filename, $frame->line );
- }
+ for my $frame (@{$e->template_stack}) {
+ li { $frame }
}
};
} else {
@@ -188,33 +160,4 @@
}
};
-sub _error_line {
-
- my ( $file, $line ) = (@_);
- if ( -w $file ) {
- my $path = $file;
- for ( map { $_->[1] } @{ Jifty->handler->mason->interp->comp_root } )
- {
- last if $path =~ s/ ^ \Q $_\E //;
- }
- if ( $path ne $file ) {
- outs('template ');
- tangent(
- url => "/__jifty/edit/mason_component$path",
- label => "$path line " . $line,
- parameters => { line => $line }
- );
- } else {
- tangent(
- url => "/__jifty/edit/library$path",
- label => "$path line " . $line,
- parameters => { line => $line }
- );
- }
- } else {
- outs( '%1 line %2', $file, $line );
- }
-
-}
-
1;
Modified: jifty/trunk/lib/Jifty/View/Declare/Handler.pm
==============================================================================
--- jifty/trunk/lib/Jifty/View/Declare/Handler.pm (original)
+++ jifty/trunk/lib/Jifty/View/Declare/Handler.pm Thu Feb 5 14:02:12 2009
@@ -6,10 +6,9 @@
use base qw/Jifty::View Class::Accessor::Fast/;
use Template::Declare;
+use HTML::Mason::Exceptions;
use Exception::Class ( 'Template::Declare::Exception' =>
{description => 'error in a Template::Declare template', alias => 'error'});
- at Template::Declare::Exception::ISA = 'HTML::Mason::Exception';
-
__PACKAGE__->mk_accessors(qw/root_class/);
@@ -57,13 +56,14 @@
}
push @{$config{roots}}, Jifty->config->framework('TemplateClass');
-
return %config;
}
=head2 show TEMPLATENAME
-Render a template. Expects that the template and any jifty methods called internally will end up being returned as a scalar, which we then print to STDOUT
+Render a template. Expects that the template and any jifty methods
+called internally will end up being returned as a scalar, which we
+then print to STDOUT
=cut
@@ -76,15 +76,17 @@
eval {
Template::Declare::Tags::show_page( $template, { %{Jifty->web->request->arguments}, %{Jifty->web->request->template_arguments || {}} } );
};
- my $err = $@;
- Template::Declare::Exception->throw($err) if $err;
-
- return; # Explicit return so TD call above is in void context, and appends instead of returning.
+ if (my $err = $@) {
+ $err->rethrow if ref $err;
+ Template::Declare::Exception->throw($err);
+ }
+ return;
}
=head2 template_exists TEMPLATENAME
-Given a template name, returns true if the template is in any of our Template::Declare template libraries. Otherwise returns false.
+Given a template name, returns true if the template is in any of our
+Template::Declare template libraries. Otherwise returns false.
=cut
@@ -93,4 +95,33 @@
return Template::Declare->resolve_template(@_);
}
+package HTML::Mason::Exception;
+no warnings 'redefine';
+
+sub template_stack {
+ my $self = shift;
+ unless ($self->{_stack}) {
+ $self->{_stack} = [reverse grep defined $_, map {$_->{from}} @{Jifty->handler->buffer->{stack}}],
+ }
+ return $self->{_stack};
+}
+
+sub as_text
+{
+ my ($self) = @_;
+ my $msg = $self->full_message;
+ my @template_stack = @{$self->template_stack};
+ if (@template_stack) {
+ my $stack = join("\n", map { sprintf(" [%s]", $_) } @template_stack);
+ return sprintf("%s\nTemplate stack:\n%s\n", $msg, $stack);
+ } else {
+ my $info = $self->analyze_error;
+ my $stack = join("\n", map { sprintf(" [%s:%d]", $_->filename, $_->line) } @{$info->{frames}});
+ return sprintf("%s\nStack:\n%s\n", $msg, $stack);
+ }
+}
+
+package Template::Declare::Exception;
+our @ISA = 'HTML::Mason::Exception';
+
1;
Modified: jifty/trunk/lib/Jifty/View/Mason/Handler.pm
==============================================================================
--- jifty/trunk/lib/Jifty/View/Mason/Handler.pm (original)
+++ jifty/trunk/lib/Jifty/View/Mason/Handler.pm Thu Feb 5 14:02:12 2009
@@ -169,7 +169,15 @@
sub template_exists {
my $self = shift;
- return $self->interp->comp_exists(@_);
+ my ($component) = @_;
+ $component =~ s{^/*}{/};
+ return 1 if $self->interp->comp_exists($component);
+
+ my $dhandler = $self->interp->dhandler_name;
+ $dhandler = "dhandler" unless defined $dhandler;
+ return if defined $dhandler and not length $dhandler;
+ return 1 if $self->interp->find_comp_upwards($component, $dhandler);
+ return 0;
}
@@ -203,30 +211,7 @@
$self->interp->set_global('$jifty_internal_request', 1) if defined $args;
my %args = $args ? %$args : $self->request_args($r);
-
- my @result;
- if (wantarray) {
- @result = eval { $self->interp->exec($comp, %args) };
- } elsif ( defined wantarray ) {
- $result[0] = eval { $self->interp->exec($comp, %args) };
- } else {
- eval { $self->interp->exec($comp, %args) };
- }
-
- if (my $err = $@) {
- my $retval = isa_mason_exception($err, 'Abort') ? $err->aborted_value :
- isa_mason_exception($err, 'Decline') ? $err->declined_value :
- rethrow_exception $err;
-
- # Unlike under mod_perl, we cannot simply return a 301 or 302
- # status and let Apache send headers, we need to explicitly
- # send this header ourself.
- Jifty->handler->send_http_header if $retval && grep { $retval eq $_ } ( 200, 301, 302 );
-
- return $retval;
- }
-
- return wantarray ? @result : defined wantarray ? $result[0] : undef;
+ $self->interp->exec($comp, %args);
}
=head2 request_args
Modified: jifty/trunk/lib/Jifty/View/Mason/Request.pm
==============================================================================
--- jifty/trunk/lib/Jifty/View/Mason/Request.pm (original)
+++ jifty/trunk/lib/Jifty/View/Mason/Request.pm Thu Feb 5 14:02:12 2009
@@ -71,36 +71,27 @@
%mods = (%{shift()}, %mods) while ref($_[0]) eq 'HASH';
my @args;
push @args, buffer => delete $mods{store} if $mods{store} and $mods{store} ne \($self->{request_buffer});
- Jifty->handler->buffer->push(@args, from => "Mason path ".(ref $_[0] ? $_[0]{path} : $_[0]));
+ my $file = (ref $_[0] ? $_[0]{path} : $_[0]);
+ Jifty->handler->buffer->push(@args, from => "Mason path $file", file => $file);
my $wantarray = wantarray;
my @result;
- eval {
- if ($wantarray) {
- @result = $self->SUPER::comp(\%mods, @_);
- } elsif (defined $wantarray) {
- $result[0] = $self->SUPER::comp(\%mods, @_);
- } else {
- $self->SUPER::comp(\%mods, @_);
- }
- };
- my $error = $@;
-
+ if ($wantarray) {
+ @result = $self->SUPER::comp(\%mods, @_);
+ } elsif (defined $wantarray) {
+ $result[0] = $self->SUPER::comp(\%mods, @_);
+ } else {
+ $self->SUPER::comp(\%mods, @_);
+ }
Jifty->handler->buffer->pop;
-
- rethrow_exception $error if $error;
return $wantarray ? @result : $result[0];
}
sub content {
my $self = shift;
- Jifty->handler->buffer->push( private => 1 );
- eval { $self->SUPER::content };
- if (my $err = $@) {
- Jifty->handler->buffer->pop;
- rethrow_exception $err;
- }
+ Jifty->handler->buffer->push( private => 1, from => "Mason call to content" );
+ $self->SUPER::content;
return Jifty->handler->buffer->pop;
}
Modified: jifty/trunk/lib/Jifty/Web.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web.pm (original)
+++ jifty/trunk/lib/Jifty/Web.pm Thu Feb 5 14:02:12 2009
@@ -776,9 +776,8 @@
# This is designed to work under CGI or FastCGI; will need an
# abstraction for mod_perl
- # Clear out the mason output, if any
- $self->mason->clear_buffer if $self->mason;
- Template::Declare->buffer->clear if(Template::Declare->buffer);
+ # Clear out the output, if any
+ Jifty->handler->buffer->clear;
my $apache = Jifty->handler->apache;
Modified: jifty/trunk/plugins.old/EmailErrors/lib/Jifty/Plugin/EmailErrors/Dispatcher.pm
==============================================================================
--- jifty/trunk/plugins.old/EmailErrors/lib/Jifty/Plugin/EmailErrors/Dispatcher.pm (original)
+++ jifty/trunk/plugins.old/EmailErrors/lib/Jifty/Plugin/EmailErrors/Dispatcher.pm Thu Feb 5 14:02:12 2009
@@ -4,7 +4,7 @@
package Jifty::Plugin::EmailErrors::Dispatcher;
use Jifty::Dispatcher -base;
-after '/__jifty/error/mason_internal_error', run {
+after ['/__jifty/error/mason_internal_error', '/errors/500'], run {
return if already_run;
return unless Jifty->web->request->continuation;
Jifty::Plugin::EmailErrors::Notification::EmailError->new->send;
Modified: jifty/trunk/t/TestApp/etc/config.yml
==============================================================================
--- jifty/trunk/t/TestApp/etc/config.yml (original)
+++ jifty/trunk/t/TestApp/etc/config.yml Thu Feb 5 14:02:12 2009
@@ -1,7 +1,4 @@
---
-framework:
- DevelMode: 0
-
application:
ThisConfigFile: etc/config.yml
EtcConfig: 1
Modified: jifty/trunk/t/TestApp/lib/TestApp/View.pm
==============================================================================
--- jifty/trunk/t/TestApp/lib/TestApp/View.pm (original)
+++ jifty/trunk/t/TestApp/lib/TestApp/View.pm Thu Feb 5 14:02:12 2009
@@ -26,6 +26,24 @@
};
};
+template '/td/template-with-error' => page {
+ outs('Before error');
+ Jifty->web->non_existent_method;
+ outs('After error');
+};
+
+template '/td/region-with-error' => sub{
+ outs('Region before');
+ Jifty->web->non_existent_method;
+ outs('Region after');
+};
+
+template '/td/call-region-with-error' => sub {
+ outs('Calling before');
+ render_region( 'error', path => '/td/region-with-error' );
+ outs('Calling after');
+};
+
template 'concrete2.html' => sub {
html {
body {
Added: jifty/trunk/t/TestApp/share/web/templates/call-region-with-error
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp/share/web/templates/call-region-with-error Thu Feb 5 14:02:12 2009
@@ -0,0 +1,5 @@
+<&|/_elements/wrapper, title => 'Jifty Test Application' &>
+Calling before
+<% Jifty->web->region( path => "/region-with-error", name => "error" ) %>
+Calling after
+</&>
Added: jifty/trunk/t/TestApp/share/web/templates/region-with-error
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp/share/web/templates/region-with-error Thu Feb 5 14:02:12 2009
@@ -0,0 +1,3 @@
+Region before
+% Jifty->web->non_existent_method;
+Region after
Modified: jifty/trunk/t/TestApp/share/web/templates/template-with-error
==============================================================================
--- jifty/trunk/t/TestApp/share/web/templates/template-with-error (original)
+++ jifty/trunk/t/TestApp/share/web/templates/template-with-error Thu Feb 5 14:02:12 2009
@@ -1,7 +1,5 @@
<&|/_elements/wrapper, title => 'Jifty Test Application' &>
-Whee!
-
-% Jifty->web->non_existant_method;
-
-Fun!
+Before error
+% Jifty->web->non_existent_method;
+After error
</&>
More information about the Jifty-commit
mailing list