diff lib/IMPL/Web/Handler/ErrorHandler.pm @ 407:c6e90e02dd17 ref20150831

renamed Lib->lib
author cin
date Fri, 04 Sep 2015 19:40:23 +0300
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/IMPL/Web/Handler/ErrorHandler.pm	Fri Sep 04 19:40:23 2015 +0300
@@ -0,0 +1,127 @@
+package IMPL::Web::Handler::ErrorHandler;
+use strict;
+
+use IMPL::Const qw(:prop);
+use IMPL::Exception();
+use IMPL::declare {
+	require => {
+		WebException => 'IMPL::Web::Exception',
+		ArgumentException => '-IMPL::InvalidArgumentException',
+		IOException => '-IMPL::IOException',
+		HttpResponse => 'IMPL::Web::HttpResponse',
+		Security => 'IMPL::Security'
+	},
+	base => {
+		'IMPL::Object' => undef,
+		'IMPL::Object::Autofill' => '@_',
+		'IMPL::Object::Serializable' => undef
+	},
+	props => [
+        errors => PROP_RW,
+        view => PROP_RW,
+        fallback => PROP_RW,
+        contentType => PROP_RW
+	]
+};
+
+sub CTOR {
+	my ($this) = @_;
+	
+	die ArgumentException->new("view") unless $this->view;
+	die ArgumentException->new("fallback") unless $this->fallback;
+	
+	$this->errors({}) unless $this->errors;
+	
+}
+
+sub Invoke {
+	my ($this,$action,$next) = @_;
+	
+	undef $@;
+	my $result;
+	eval {
+        $result = $next ? $next->($action) : undef;
+	};
+	
+	if (my $err = $@) {
+	    
+		my $vars = {
+			error => $err,
+			result      => $result,
+	        request     => sub { $action },
+	        app         => $action->application,
+	        location    => $action->context->{resourceLocation},
+	        resource    => $action->context->{resource},
+	        document    => {},
+	        session     => sub { Security->context },
+	        user        => sub { Security->principal },
+	        security    => sub { $action->security }
+		};
+		
+		my $status = "500 Internal Server Error";
+		
+		if (eval { $err->isa(WebException) }) {
+			$status = $err->status;
+		}
+		
+		my ($code) = ($status =~ m/^(\d+)/);
+		
+        my $text = $this->view->display(
+        	$err,
+        	$this->errors->{$code} || $this->fallback,
+        	$vars
+		);
+        
+        $result = HttpResponse->new(
+            status => $status,
+            type => $this->contentType,
+            charset => 'utf-8',
+            headers => eval{ $err->headers } || {},
+            body => $text
+        );
+	}
+	
+	return $result;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+C<IMPL::Web::Handler::ErrorHandler> - обертка для обработки исключений.
+
+=head1 SYNOPSIS
+
+Используется в цеопчке обработчиков приложения.
+
+=begin code xml
+
+    <handlers type="ARRAY">
+        <item type="IMPL::Web::Handler::ErrorHandler">
+            <contentType>text/html</contentType>
+            <loader refid="tt-loader"/>
+            <errors type="HASH">
+                <error extname="500">errors/500</error>
+                <error extname="404">errors/404</error>
+                <error extname="403">errors/403</error>
+            </errors>
+            <fallback>errors/500</fallback>
+        </item>
+    </handlers>
+
+=end code xml
+
+=head1 DESCRIPTION
+
+Позволяет создать представление для ресурса в случае ошибки, для этого
+используется соответствие представлений и кодов ошибок.
+
+В результате обработчик либо прозрачно передает результат вышестоящего
+обработчика нижестоящему, либо создает C<IMPL::Web::HttpResponse> с
+соответствующим статусом и содержанием. 
+
+=cut
\ No newline at end of file