view Lib/IMPL/Web/Handler/ErrorHandler.pm @ 250:129e48bb5afb

DOM refactoring ObjectToDOM methods are virtual QueryToDOM uses inflators Fixed transform for the complex values in the ObjectToDOM QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author sergey
date Wed, 07 Nov 2012 04:17:53 +0400
parents 3cebcf6fdb9b
children 32aceba4ee6d
line wrap: on
line source

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'
	},
	base => {
		'IMPL::Object' => undef,
		'IMPL::Object::Autofill' => '@_',
		'IMPL::Object::Serializable' => undef
	},
	props => [
        errors => PROP_RW,
        loader => PROP_RW,
        fallback => PROP_RW,
        contentType => PROP_RW
	]
};

sub CTOR {
	my ($this) = @_;
	
	die ArgumentException->new("loader") unless $this->loader;
	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
		};
		
		my $status = "500 Internal Server Error";
		
		if (eval { $err->isa(WebException) }) {
			$status = $err->status;
		}
		
		my ($code) = ($status =~ m/^(\d+)/);
		
		my $doc = $this->loader->document(
            $this->errors->{$code} || $this->fallback,
            $vars
        );
        
        my $text = $doc->Render($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