docs and new test cases
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
old mode 100755 (executable)
new mode 100644 (file)
index 88e9af2..14ca58e
@@ -127,7 +127,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 __PACKAGE__->_encode_check(Encode::FB_CROAK | Encode::LEAVE_SRC);
 
 # Remember to update this in Catalyst::Runtime as well!
-our $VERSION = '5.90069_003';
+our $VERSION = '5.90077';
 
 sub import {
     my ( $class, @arguments ) = @_;
@@ -518,6 +518,9 @@ Add a new error.
 
     $c->error('Something bad happened');
 
+Calling this will always return an arrayref (if there are no errors it
+will be an empty arrayref.
+
 =cut
 
 sub error {
@@ -562,6 +565,29 @@ Returns true if you have errors
 
 sub has_errors { scalar(@{shift->error}) ? 1:0 }
 
+=head2 $c->last_error
+
+Returns the most recent error in the stack (the one most recently added...)
+or nothing if there are no errors.
+
+=cut
+
+sub last_error { my ($err, @errs) = @{shift->error}; return $err }
+
+=head2 shift_errors
+
+shifts the most recently added error off the error stack and returns if.  Returns
+nothing if there are nomore errors.
+
+=cut
+
+sub shift_errors {
+    my ($self) = @_;
+    my ($err, @errors) = @{$self->error};
+    $self->{error} = \@errors;
+    return $err;
+}
+
 sub _comp_search_prefixes {
     my $c = shift;
     return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
@@ -1775,7 +1801,16 @@ sub execute {
 
     if ( my $error = $@ ) {
         #rethow if this can be handled by middleware
-        if(blessed $error && ($error->can('as_psgi') || $error->can('code'))) {
+        if(
+          !$c->config->{always_catch_http_exceptions} &&
+          blessed $error && (
+            $error->can('as_psgi') ||
+            (
+              $error->can('code') &&
+              $error->code =~m/^[1-5][0-9][0-9]$/
+            )
+          )
+        ) {
             foreach my $err (@{$c->error}) {
                 $c->log->error($err);
             }
@@ -1957,6 +1992,7 @@ sub finalize_error {
     } else {
         my ($error) = @{$c->error};
         if(
+          !$c->config->{always_catch_http_exceptions} &&
           blessed $error &&
           ($error->can('as_psgi') || $error->can('code'))
         ) {
@@ -2101,7 +2137,16 @@ sub handle_request {
         $status = $c->finalize;
     } catch {
         #rethow if this can be handled by middleware
-        if(blessed $_ && ($_->can('as_psgi') || $_->can('code'))) {
+        if(
+          !$class->config->{always_catch_http_exceptions} &&
+          blessed($_) && (
+            $_->can('as_psgi') ||
+            (
+              $_->can('code') &&
+              $_->code =~m/^[1-5][0-9][0-9]$/
+            )
+          )
+        ) {
             $_->can('rethrow') ? $_->rethrow : croak $_;
         }
         chomp(my $error = $_);
@@ -3071,6 +3116,7 @@ sub _handle_unicode_decoding {
 
     return unless defined $value;
 
+    ## I think this mess is to support the old nested
     if ( ref $value eq 'ARRAY' ) {
         foreach ( @$value ) {
             $_ = $self->_handle_unicode_decoding($_);
@@ -3090,6 +3136,8 @@ sub _handle_unicode_decoding {
 
 sub _handle_param_unicode_decoding {
     my ( $self, $value ) = @_;
+    return unless defined $value; # not in love with just ignoring undefs - jnap
+
     my $enc = $self->encoding;
     return try {
         Encode::is_utf8( $value ) ?
@@ -3415,9 +3463,15 @@ sub default_data_handlers {
             ->can('build_cgi_struct')->($params);
       },
       'application/json' => sub {
-          Class::Load::load_first_existing_class('JSON::MaybeXS', 'JSON')
-            ->can('decode_json')->(do { local $/; $_->getline });
-      },
+          my ($fh, $req) = @_;
+          my $parser = Class::Load::load_first_existing_class('JSON::MaybeXS', 'JSON');
+          my $slurped;
+          return eval { 
+            local $/;
+            $slurped = $fh->getline;
+            $parser->can("decode_json")->($slurped);
+          } || Catalyst::Exception->throw(sprintf "Error Parsing POST '%s', Error: %s", (defined($slurped) ? $slurped : 'undef') ,$@);
+        },
     };
 }
 
@@ -3487,6 +3541,13 @@ There are a number of 'base' config variables which can be set:
 
 =item *
 
+C<always_catch_http_exceptions> - As of version 5.90060 Catalyst
+rethrows errors conforming to the interface described by
+L<Plack::Middleware::HTTPExceptions> and lets the middleware deal with it.
+Set true to get the deprecated behaviour and have Catakyst catch HTTP exceptions.
+
+=item *
+
 C<default_model> - The default model picked if you say C<< $c->model >>. See L<< /$c->model($name) >>.
 
 =item *