Version 1.02
[catagits/Catalyst-Action-REST.git] / lib / Catalyst / Action / Serialize.pm
index cc1f838..73855b3 100644 (file)
@@ -7,9 +7,15 @@ extends 'Catalyst::Action::SerializeBase';
 use Module::Pluggable::Object;
 use MRO::Compat;
 
-our $VERSION = '0.81';
+our $VERSION = '1.02';
 $VERSION = eval $VERSION;
 
+has _encoders => (
+   is => 'ro',
+   isa => 'HashRef',
+   default => sub { {} },
+);
+
 sub execute {
     my $self = shift;
     my ( $controller, $c ) = @_;
@@ -17,9 +23,9 @@ sub execute {
     $self->maybe::next::method(@_);
 
     return 1 if $c->req->method eq 'HEAD';
-    return 1 if length( $c->response->body );
+    return 1 if $c->response->has_body;
     return 1 if scalar @{ $c->error };
-    return 1 if $c->response->status =~ /^(?:204|3\d\d)$/;
+    return 1 if $c->response->status =~ /^(?:204)$/;
 
     my ( $sclass, $sarg, $content_type ) =
       $self->_load_content_plugins( "Catalyst::Action::Serialize",
@@ -36,18 +42,21 @@ sub execute {
     $c->log->debug(
         "Serializing with $sclass" . ( $sarg ? " [$sarg]" : '' ) ) if $c->debug;
 
+    $self->_encoders->{$sclass} ||= $sclass->new;
+    my $sobj = $self->_encoders->{$sclass};
+
     my $rc;
     eval {
         if ( defined($sarg) ) {
-            $rc = $sclass->execute( $controller, $c, $sarg );
+            $rc = $sobj->execute( $controller, $c, $sarg );
         } else {
-            $rc = $sclass->execute( $controller, $c );
+            $rc = $sobj->execute( $controller, $c );
         }
     };
     if ($@) {
-        return $self->_serialize_bad_request( $c, $content_type, $@ );
+        return $self->serialize_bad_request( $c, $content_type, $@ );
     } elsif (!$rc) {
-        return $self->_unsupported_media_type( $c, $content_type );
+        return $self->unsupported_media_type( $c, $content_type );
     }
 
     return 1;
@@ -55,6 +64,8 @@ sub execute {
 
 __PACKAGE__->meta->make_immutable;
 
+1;
+
 =head1 NAME
 
 Catalyst::Action::Serialize - Serialize Data in a Response
@@ -107,7 +118,7 @@ Takes a hashref, mapping Content-Types to a given serializer plugin.
 This is the 'fall-back' Content-Type if none of the requested or acceptable
 types is found in the L</map>. It must be an entry in the L</map>.
 
-=head2 stash_key 
+=head2 stash_key
 
 Specifies the key of the stash entry holding the data that is to be serialized.
 So if the value is "rest", we will serialize the data under:
@@ -127,7 +138,14 @@ perhaps for debugging.
 
 Daisuke Maki pointed out that early versions of this Action did not play
 well with others, or generally behave in a way that was very consistent
-with the rest of Catalyst. 
+with the rest of Catalyst.
+
+=head1 CUSTOM ERRORS
+
+For building custom error responses when serialization fails, you can create
+an ActionRole (and use L<Catalyst::Controller::ActionRole> to apply it to the
+C<end> action) which overrides C<unsupported_media_type> and/or C<_serialize_bad_request>
+methods.
 
 =head1 SEE ALSO