view Lib/IMPL/Web/Handler/ErrorHandler.pm @ 245:7c517134c42f

Added Unsupported media type Web exception corrected resourceLocation setting in the resource Implemented localizable resources for text messages fixed TT view scopings, INIT block in controls now sets globals correctly.
author sergey
date Mon, 29 Oct 2012 03:15:22 +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