use HTTP::Headers;
use Time::HiRes qw/gettimeofday tv_interval/;
use Text::ASCIITable;
+use Catalyst::Exception;
use Catalyst::Request;
use Catalyst::Request::Upload;
use Catalyst::Response;
$Data::Dumper::Terse = 1;
__PACKAGE__->mk_classdata('components');
-__PACKAGE__->mk_accessors(qw/counter request response state/);
+__PACKAGE__->mk_accessors(qw/counter depth request response state/);
*comp = \&component;
*req = \&request;
our $COUNT = 1;
our $START = time;
our $RECURSION = 1000;
+our $DETACH = "catalyst_detach\n";
=head1 NAME
Returns a hashref containing coderefs and execution counts.
(Needed for deep recursion detection)
+=item $c->depth
+
+Returns the actual forward depth.
+
=item $c->error
=item $c->error($error, ...)
$action = "-> $action" if $callsub =~ /forward$/;
}
+ $c->{depth}++;
eval {
if ( $c->debug )
{
- my ( $elapsed, @state ) = $c->benchmark( $code, $class, $c, @{ $c->req->args } );
+ my ( $elapsed, @state ) =
+ $c->benchmark( $code, $class, $c, @{ $c->req->args } );
push @{ $c->{stats} }, [ $action, sprintf( '%fs', $elapsed ) ];
$c->state(@state);
}
else { $c->state( &$code( $class, $c, @{ $c->req->args } ) || 0 ) }
};
+ $c->{depth}--;
if ( my $error = $@ ) {
- unless ( ref $error ) {
- chomp $error;
- $error = qq/Caught exception "$error"/;
- }
+ if ( $error eq $DETACH ) { die $DETACH if $c->{depth} > 1 }
+ else {
+ unless ( ref $error ) {
+ chomp $error;
+ $error = qq/Caught exception "$error"/;
+ }
- $c->log->error($error);
- $c->error($error);
- $c->state(0);
+ $c->log->error($error);
+ $c->error($error);
+ $c->state(0);
+ }
}
return $c->state;
}
if ( $#{ $c->error } >= 0 ) {
$c->finalize_error;
}
-
+
if ( !$c->response->body && $c->response->status == 200 ) {
$c->finalize_error;
}
if ( $c->response->body && !$c->response->content_length ) {
$c->response->content_length( bytes::length( $c->response->body ) );
}
-
+
if ( $c->response->status =~ /^(1\d\d|[23]04)$/ ) {
$c->response->headers->remove_header("Content-Length");
$c->response->body('');
}
-
+
if ( $c->request->method eq 'HEAD' ) {
$c->response->body('');
}
my $c = bless {
counter => {},
+ depth => 0,
request => Catalyst::Request->new(
{
arguments => [],
$c->prepare_path;
$c->prepare_action;
- my $method = $c->req->method || '';
- my $path = $c->req->path || '';
- my $address = $c->req->address || '';
+ my $method = $c->req->method || '';
+ my $path = $c->req->path || '';
+ my $address = $c->req->address || '';
$c->log->debug(qq/"$method" request for "$path" from $address/)
if $c->debug;
my $self = shift;
# Initialize our data structure
- $self->components( {} );
+ $self->components( {} );
$self->setup_components;
if ( $self->debug ) {
my $t = Text::ASCIITable->new;
- $t->setOptions( 'hide_HeadRow', 1 );
+ $t->setOptions( 'hide_HeadRow', 1 );
$t->setOptions( 'hide_HeadLine', 1 );
$t->setCols('Class');
$t->setColWidth( 'Class', 75, 1 );
$self->log->debug( 'Loaded components', $t->draw )
if ( @{ $t->{tbl_rows} } );
}
-
+
# Add our self to components, since we are also a component
- $self->components->{ $self } = $self;
+ $self->components->{$self} = $self;
$self->setup_actions;
sub setup_components {
my $self = shift;
-
+
my $callback = sub {
my ( $component, $context ) = @_;
-
+
unless ( $component->isa('Catalyst::Base') ) {
return $component;
}
my $instance;
- eval {
- $instance = $component->new( $context, $config );
- };
+ eval { $instance = $component->new( $context, $config ); };
if ( my $error = $@ ) {
+
chomp $error;
- die qq/Couldn't instantiate component "$component", "$error"/;
+
+ Catalyst::Exception->throw(
+ message => qq/Couldn't instantiate component "$component", "$error"/
+ );
}
return $instance;
eval {
Module::Pluggable::Fast->import(
- name => '_components',
- search => [
+ name => '_components',
+ search => [
"$self\::Controller", "$self\::C",
"$self\::Model", "$self\::M",
"$self\::View", "$self\::V"
};
if ( my $error = $@ ) {
+
chomp $error;
- die qq/Couldn't load components "$error"/;
+
+ Catalyst::Exception->throw(
+ message => qq/Couldn't load components "$error"/
+ );
}
for my $component ( $self->_components($self) ) {