diff --git a/app.psgi b/app.psgi index ffc1d3c83..d42c34d7a 100644 --- a/app.psgi +++ b/app.psgi @@ -13,8 +13,8 @@ builder { # Open/close the WebGUI::Session at the outer-most onion layer enable '+WebGUI::Middleware::Session', - config => $wg->config;#, - #error_docs => { 500 => "$root/www/maintenance.html" }; + config => $wg->config, + error_docs => { 500 => "$root/www/maintenance.html" }; # Return the app $wg; diff --git a/lib/WebGUI/Exception.pm b/lib/WebGUI/Exception.pm index 2e28b1231..cb9755d62 100644 --- a/lib/WebGUI/Exception.pm +++ b/lib/WebGUI/Exception.pm @@ -264,6 +264,12 @@ use Exception::Class ( description => "Couldn't establish a connection.", fields => [qw{ resource }], }, + + + 'WebGUI::Error::Fatal' => { + isa => 'WebGUI::Error', + description => "Fatal error that should be shown to all site visitors.", + }, ); diff --git a/lib/WebGUI/Middleware/Debug.pm b/lib/WebGUI/Middleware/Debug.pm deleted file mode 100644 index 6098687bc..000000000 --- a/lib/WebGUI/Middleware/Debug.pm +++ /dev/null @@ -1,39 +0,0 @@ -package WebGUI::Middleware::Debug; -use strict; -use parent qw(Plack::Middleware); -use Plack::Middleware::StackTrace; -use Plack::Middleware::Debug; -use Plack::Middleware::HttpExceptions; - -=head1 NAME - -WebGUI::Middleware::Debug - - -=head1 DESCRIPTION - -This is PSGI middleware for WebGUI that - -=cut - -sub call { - my ( $self, $env ) = @_; - - my $session = $env->{'webgui.session'} or die 'WebGUI::Session missing'; - - my $app = $self->app; - - if ( $session->log->canShowDebug ) { - warn 'seeing webgui.debug'; - $env->{'webgui.debug'} = 1; - $app = Plack::Middleware::StackTrace->wrap($app); - $app = Plack::Middleware::Debug->wrap( $app, - panels => [qw(Environment Response Timer Memory Session DBITrace PerlConfig Response)] ); - } - - # Turn exceptions into HTTP errors - $app = Plack::Middleware::HTTPExceptions->wrap( $app ); - - return $app->($env); -} - -1; diff --git a/lib/WebGUI/Middleware/HTTPExceptions.pm b/lib/WebGUI/Middleware/HTTPExceptions.pm new file mode 100644 index 000000000..132747452 --- /dev/null +++ b/lib/WebGUI/Middleware/HTTPExceptions.pm @@ -0,0 +1,36 @@ +package WebGUI::Middleware::HTTPExceptions; +use strict; +use parent qw(Plack::Middleware::HTTPExceptions); + +=head1 NAME + +WebGUI::Middleware::HTTPExceptions - Converts Exceptions into HTTP Errors + +=head1 DESCRIPTION + +This is PSGI middleware for WebGUI that detects exceptions and turns +them into HTTP Errors. This class is a subclass of L + +=cut + +use Carp (); +use Try::Tiny; +use Scalar::Util 'blessed'; +use HTTP::Status (); + +sub transform_error { + my $self = shift; + my ($e, $env) = @_; + + # Handle WebGUI::Error::Fatal errors specially, since unlike most 500 + # errors we actually want the user to see the error message (generated by + # $session->log->fatal) + if (blessed $e && $e->isa('WebGUI::Error::Fatal')) { + my $message = $e->message; + return [ 500, [ 'Content-Type' => 'text/html', 'Content-Length' => length($message) ], [ $message ] ]; + } else { + $self->SUPER::transform_error(@_); + } +} + +1; \ No newline at end of file diff --git a/lib/WebGUI/Middleware/Session.pm b/lib/WebGUI/Middleware/Session.pm index 069bc3506..b847adc9d 100644 --- a/lib/WebGUI/Middleware/Session.pm +++ b/lib/WebGUI/Middleware/Session.pm @@ -6,7 +6,7 @@ use WebGUI::Session; use Try::Tiny; use Plack::Middleware::StackTrace; use Plack::Middleware::Debug; -use Plack::Middleware::HTTPExceptions; +use WebGUI::Middleware::HTTPExceptions; use Plack::Middleware::ErrorDocument; use Plack::Util::Accessor qw( config error_docs ); @@ -31,20 +31,19 @@ and not worry about closing it. sub call { my ( $self, $env ) = @_; - my $app = $self->app; + my $app = $self->app; my $config = $self->config or die 'Mandatory config parameter missing'; my $session = try { $env->{'webgui.session'} = WebGUI::Session->open( $config->getWebguiRoot, $config, $env ); }; - - if (!$session) { + + if ( !$session ) { + # We don't have access to a db connection to find out if the user is allowed to see # a verbose error message or not, so resort to a generic Internal Server Error # (using the error_docs mapping) - return Plack::Middleware::ErrorDocument->wrap( - sub { [ 500, [], [] ] }, - %{ $self->error_docs } )->($env); + return Plack::Middleware::ErrorDocument->wrap( sub { [ 500, [], [] ] }, %{ $self->error_docs } )->($env); } my $debug = $session->log->canShowDebug; @@ -55,7 +54,7 @@ sub call { } # Turn exceptions into HTTP errors - $app = Plack::Middleware::HTTPExceptions->wrap($app); + $app = WebGUI::Middleware::HTTPExceptions->wrap($app); # HTTP error document mapping if ( !$debug && $self->error_docs ) { diff --git a/lib/WebGUI/Session/ErrorHandler.pm b/lib/WebGUI/Session/ErrorHandler.pm index 783247567..f14713f51 100644 --- a/lib/WebGUI/Session/ErrorHandler.pm +++ b/lib/WebGUI/Session/ErrorHandler.pm @@ -257,8 +257,10 @@ If this problem persists, please contact us with what you were trying to do and END_HTML } - # Fatal errors cause an exception to be thrown - WebGUI::Error->throw( error => $error ); + # Fatal errors cause an exception to be thrown - use WebGUI::Error::Fatal so + # that WebGUI knows to show this error message to all site users (instead of showing + # non-debug users the generic error screen) + WebGUI::Error::Fatal->throw( error => $error ); }