Unicode plugin - rework exception handler
Wallace Reis [Sun, 26 May 2013 14:53:58 +0000 (16:53 +0200)]
For apps in the third case (doing its own decoding/encoding), we are
not setting an ->encoding object and then request cycle might blow
up during prepare time (when we would do the params decoding). Thus,
we change the default behavior from rethrow of this exception to a
simple warning.

lib/Catalyst/Plugin/Unicode/Encoding.pm
t/lib/ACLTestApp.pm
t/lib/ChainedActionsApp.pm
t/lib/TestAppDoubleAutoBug.pm
t/lib/TestAppIndexDefault.pm
t/lib/TestAppMatchSingleArg.pm
t/lib/TestAppOneView.pm
t/lib/TestAppWithoutUnicode.pm [new file with mode: 0644]
t/lib/TestAppWithoutUnicode/Controller/Root.pm [new file with mode: 0644]
t/unicode_plugin_no_encoding.t [new file with mode: 0644]

index c1c67d9..402087e 100644 (file)
@@ -172,7 +172,8 @@ sub _handle_param_unicode_decoding {
 
 sub handle_unicode_encoding_exception {
     my ( $self, $exception_ctx ) = @_;
-    die $exception_ctx->{error_msg};
+    $self->log->warn($exception_ctx->{error_msg});
+    return $exception_ctx->{'param_value'};
 }
 
 1;
index ec87027..2b7a010 100644 (file)
@@ -5,10 +5,13 @@ use strict;
 use warnings;
 use MRO::Compat;
 use Scalar::Util ();
+use TestLogger;
 
 use base qw/Catalyst Catalyst::Controller/;
 use Catalyst qw//;
 
+__PACKAGE__->log(TestLogger->new);
+
 sub execute {
     my $c = shift;
     my ( $class, $action ) = @_;
index 375ce10..3be4faf 100644 (file)
@@ -1,6 +1,7 @@
 package ChainedActionsApp;
 use Moose;
 use namespace::autoclean;
+use TestLogger;
 
 use Catalyst::Runtime 5.80;
 
@@ -16,6 +17,8 @@ __PACKAGE__->config(
   disable_component_regex_fallback => 1,
 );
 
+__PACKAGE__->log(TestLogger->new);
+
 __PACKAGE__->setup;
 
 1;
index 524ed8b..1044a30 100644 (file)
@@ -3,6 +3,7 @@ use warnings;
 
 package TestAppDoubleAutoBug;
 
+use TestLogger;
 use Catalyst qw/
     Test::Errors
     Test::Headers
@@ -13,6 +14,8 @@ our $VERSION = '0.01';
 
 __PACKAGE__->config( name => 'TestAppDoubleAutoBug', root => '/some/dir' );
 
+__PACKAGE__->log(TestLogger->new);
+
 __PACKAGE__->setup;
 
 sub execute {
index 9a129cb..57e3f85 100644 (file)
@@ -1,8 +1,11 @@
 package TestAppIndexDefault;
 use strict;
 use warnings;
+use TestLogger;
 use Catalyst;
 
+__PACKAGE__->log(TestLogger->new);
+
 __PACKAGE__->setup;
 
 1;
index 8f87993..6687eac 100644 (file)
@@ -1,8 +1,11 @@
 package TestAppMatchSingleArg;
 use strict;
 use warnings;
+use TestLogger;
 use Catalyst;
 
+__PACKAGE__->log(TestLogger->new);
+
 __PACKAGE__->setup;
 
 1;
index 59354b3..33fafea 100644 (file)
@@ -1,8 +1,11 @@
 package TestAppOneView;
 use strict;
 use warnings;
+use TestLogger;
 use Catalyst;
 
+__PACKAGE__->log(TestLogger->new);
+
 __PACKAGE__->setup;
 
 1;
diff --git a/t/lib/TestAppWithoutUnicode.pm b/t/lib/TestAppWithoutUnicode.pm
new file mode 100644 (file)
index 0000000..5cb3d81
--- /dev/null
@@ -0,0 +1,14 @@
+package TestAppWithoutUnicode;
+use strict;
+use warnings;
+use TestLogger;
+use base qw/Catalyst/;
+use Catalyst qw/Params::Nested/;
+
+__PACKAGE__->config('name' => 'TestAppWithoutUnicode');
+
+__PACKAGE__->log(TestLogger->new);
+
+__PACKAGE__->setup;
+
+1;
diff --git a/t/lib/TestAppWithoutUnicode/Controller/Root.pm b/t/lib/TestAppWithoutUnicode/Controller/Root.pm
new file mode 100644 (file)
index 0000000..4328fb9
--- /dev/null
@@ -0,0 +1,17 @@
+package TestAppWithoutUnicode::Controller::Root;
+
+use Moose;
+BEGIN { extends 'Catalyst::Controller' }
+use Encode qw(encode_utf8 decode_utf8);
+
+__PACKAGE__->config( namespace => q{} );
+
+sub default : Private {
+    my ( $self, $c ) = @_;
+    my $param = decode_utf8($c->request->parameters->{'myparam'});
+    $c->response->body( encode_utf8($param) );
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
diff --git a/t/unicode_plugin_no_encoding.t b/t/unicode_plugin_no_encoding.t
new file mode 100644 (file)
index 0000000..5d0dfe3
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Test::More;
+use utf8;
+
+# setup library path
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+
+use Catalyst::Test 'TestAppWithoutUnicode';
+use Encode;
+use HTTP::Request::Common;
+use URI::Escape qw/uri_escape_utf8/;
+use HTTP::Status 'is_server_error';
+
+my $encode_str = "\x{e3}\x{81}\x{82}"; # e38182 is japanese 'あ'
+my $decode_str = Encode::decode('utf-8' => $encode_str);
+my $escape_str = uri_escape_utf8($decode_str);
+
+check_parameter(GET "/?myparam=$escape_str");
+
+sub check_parameter {
+    my ( undef, $c ) = ctx_request(shift);
+    is $c->res->output => $encode_str;
+
+    my $myparam = $c->req->param('myparam');
+    ok !utf8::is_utf8($myparam);
+    is $myparam => $encode_str;
+
+    is scalar(@TestLogger::ELOGS), 2
+        or diag Dumper(\@TestLogger::ELOGS);
+    like $TestLogger::ELOGS[0], qr/method \"decode\"/;
+}
+
+done_testing;