X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine.pm;h=8a0d54cf60c293365879007bcf2b015aed5bd239;hb=f56990fa9c318716c04de16af8f9dc19412fc226;hp=6af7d74f6e86fe880bc4ef2b47ed101cb15cc768;hpb=d290eee8f1f2097f3edcf04bfae5cb6d78f2e5b2;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Engine.pm b/lib/Catalyst/Engine.pm index 6af7d74..8a0d54c 100644 --- a/lib/Catalyst/Engine.pm +++ b/lib/Catalyst/Engine.pm @@ -10,18 +10,17 @@ use HTML::Entities; 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; use Catalyst::Utils; -require Module::Pluggable::Fast; - # For pretty dumps $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; @@ -34,6 +33,7 @@ __PACKAGE__->mk_accessors(qw/counter request response state/); our $COUNT = 1; our $START = time; our $RECURSION = 1000; +our $DETACH = "catalyst_detach\n"; =head1 NAME @@ -107,6 +107,10 @@ sub component { 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, ...) @@ -160,26 +164,32 @@ sub execute { $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; } @@ -204,7 +214,7 @@ sub finalize { if ( $#{ $c->error } >= 0 ) { $c->finalize_error; } - + if ( !$c->response->body && $c->response->status == 200 ) { $c->finalize_error; } @@ -212,12 +222,12 @@ sub finalize { 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(''); } @@ -276,7 +286,7 @@ sub finalize_error { my ( $title, $error, $infos ); if ( $c->debug ) { - $error = join '
', @{ $c->error }; + $error = join '', map { '' . encode_entities($_) . '' } @{ $c->error }; $error ||= 'No output'; $title = $name = "$name on Catalyst $Catalyst::VERSION"; my $req = encode_entities Dumper $c->req; @@ -352,6 +362,12 @@ sub finalize_error { margin: 4px; -moz-border-radius: 10px; } + code.error { + display: block; + margin: 1em 0; + overflow: auto; + white-space: pre; + } @@ -406,8 +422,7 @@ sub handler { $t->setColWidth( 'Time', 9, 1 ); for my $stat (@stats) { $t->addRow( $stat->[0], $stat->[1] ) } - $class->log->info( "Request took $elapsed" . "s ($av/s)", - $t->draw ); + $class->log->info( "Request took ${elapsed}s ($av/s)\n" . $t->draw ); } else { $status = &$handler } @@ -434,6 +449,7 @@ sub prepare { my $c = bless { counter => {}, + depth => 0, request => Catalyst::Request->new( { arguments => [], @@ -473,9 +489,9 @@ sub prepare { $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; @@ -508,7 +524,7 @@ sub prepare { my $value = defined($param) ? $param : ''; $t->addRow( $key, $value ); } - $c->log->debug( 'Parameters are', $t->draw ); + $c->log->debug( "Parameters are:\n" . $t->draw ); } return $c; @@ -658,99 +674,6 @@ Returns a C object. my $res = $c->res; -=item $class->setup - -Setup. - - MyApp->setup; - -=cut - -sub setup { - my $self = shift; - - # Initialize our data structure - $self->components( {} ); - - $self->setup_components; - - if ( $self->debug ) { - my $t = Text::ASCIITable->new; - $t->setOptions( 'hide_HeadRow', 1 ); - $t->setOptions( 'hide_HeadLine', 1 ); - $t->setCols('Class'); - $t->setColWidth( 'Class', 75, 1 ); - $t->addRow($_) for sort keys %{ $self->components }; - $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->setup_actions; - - if ( $self->debug ) { - my $name = $self->config->{name} || 'Application'; - $self->log->info("$name powered by Catalyst $Catalyst::VERSION"); - } -} - -=item $class->setup_components - -Setup components. - -=cut - -sub setup_components { - my $self = shift; - - my $callback = sub { - my ( $component, $context ) = @_; - - unless ( $component->isa('Catalyst::Base') ) { - return $component; - } - - my $suffix = Catalyst::Utils::class2classsuffix($component); - my $config = $self->config->{$suffix} || {}; - - my $instance; - - eval { - $instance = $component->new( $context, $config ); - }; - - if ( my $error = $@ ) { - chomp $error; - die qq/Couldn't instantiate component "$component", "$error"/; - } - - return $instance; - }; - - eval { - Module::Pluggable::Fast->import( - name => '_components', - search => [ - "$self\::Controller", "$self\::C", - "$self\::Model", "$self\::M", - "$self\::View", "$self\::V" - ], - callback => $callback - ); - }; - - if ( my $error = $@ ) { - chomp $error; - die qq/Couldn't load components "$error"/; - } - - for my $component ( $self->_components($self) ) { - $self->components->{ ref $component || $component } = $component; - } -} - =item $c->state Contains the return value of the last executed action.