# This file documents the revision history for Perl extension Catalyst.
+5.90115 - 2017-05-01
+ - fixes for silent bad behavior in Catalyst::ScriptRole and 'ensure_class_loaded'
+ (hobbs++)
+ - do not require MXRWO if Moose is new enough to have cored it (ether++)
+ - documentation improvements (ether++)
+ - Encoding documentation improvements (colinnewell++)
+
5.90114 - 2016-12-19
- Fixed regression introduced in the last version (5.90113) which caused
application to hang when the action private name contained a string
requires 'Data::OptList';
requires 'Moose' => '1.03';
requires 'MooseX::MethodAttributes::Role::AttrContainer::Inheritable' => '0.24';
-requires 'MooseX::Role::WithOverloading' => '0.09';
+requires 'MooseX::Role::WithOverloading' => '0.09' unless can_use('Moose', '2.1300');
requires 'Carp' => '1.25';
requires 'Class::C3::Adopt::NEXT' => '0.07';
requires 'CGI::Simple::Cookie' => '1.109';
'license', => 'http://dev.perl.org/licenses/',
'homepage', => 'http://dev.catalyst.perl.org/',
# r/w: catagits@git.shadowcat.co.uk:Catalyst-Runtime.git
+ # web: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits/Catalyst-Runtime.git;a=summary
'repository', => 'git://git.shadowcat.co.uk/catagits/Catalyst-Runtime.git',
);
and access it from the stash.
-Keep in mind that the C<end> method used is that of the caller action. So a C<$c-E<gt>detach> inside a forwarded action would run the C<end> method from the original action requested.
+Keep in mind that the C<end> method used is that of the caller action. So a C<< $c->detach >> inside a forwarded action would run the C<end> method from the original action requested.
=cut
(defined($res->body)) and
(ref(\$res->body) eq 'SCALAR')
) {
+ # if you are finding yourself here and your body is already encoded correctly
+ # and you want to turn this off, use $c->clear_encoding to prevent encoding
+ # at this step, or set encoding to undef in the config to do so for the whole
+ # application. See the ENCODING documentaiton for better notes.
$c->res->body( $c->encoding->encode( $c->res->body, $c->_encode_check ) );
# Set the charset if necessary. This might be a bit bonkers since encodable response
C<abort_chain_on_error_fix>
-When there is an error in an action chain, the default behavior is to continue
-processing the remaining actions and then catch the error upon chain end. This
-can lead to running actions when the application is in an unexpected state. If
-you have this issue, setting this config value to true will promptly exit a
-chain when there is an error raised in any action (thus terminating the chain
-early.)
+Defaults to true.
-use like:
+When there is an error in an action chain, the default behavior is to
+abort the processing of the remaining actions to avoid running them
+when the application is in an unexpected state.
- __PACKAGE__->config(abort_chain_on_error_fix => 1);
+Before version 5.90070, the default used to be false. To keep the old
+behaviour, you can explicitely set the value to false. E.g.
+
+ __PACKAGE__->config(abort_chain_on_error_fix => 0);
+
+If this setting is set to false, then the remaining actions are
+performed and the error is caught at the end of the chain.
-In the future this might become the default behavior.
=item *
This is recommended for temporary backwards compatibility only.
+To turn it off for a single request use the L<clear_encoding>
+method to turn off encoding for this request. This can be useful
+when you are setting the body to be an arbitrary block of bytes,
+especially if that block happens to be a block of UTF8 text.
+
Encoding is automatically applied when the content-type is set to
a type that can be encoded. Currently we encode when the content type
matches the following regular expression:
Andrew Bramble
-Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
+Andrew Ford <A.Ford@ford-mason.co.uk>
Andrew Ruthven
davewood: David Schmidt <davewood@cpan.org>
-David Kamholz E<lt>dkamholz@cpan.orgE<gt>
+David Kamholz <dkamholz@cpan.org>
David Naughton, C<naughton@umn.edu>
=head1 AUTHOR
-Florian Ragwitz E<lt>rafl@debian.orgE<gt>
+Florian Ragwitz <rafl@debian.org>
=end stopwords
its arguments. If it doesn't expect any, just specify
C<:CaptureArgs(0)>. The captures get passed to the action's C<@_> right
after the context, but you can also find them as array references in
-C<$c-E<gt>request-E<gt>captures-E<gt>[$level]>. The C<$level> is the
+C<< $c->request->captures->[$level] >>. The C<$level> is the
level of the action in the chain that captured the parts of the path.
An action that is part of a chain (that is, one that has a C<:Chained>
Just as with C<:CaptureArgs>, the arguments get passed to the action in
C<@_> after the context object. They can also be reached through
-C<$c-E<gt>request-E<gt>arguments>.
+C<< $c->request->arguments >>.
You should see 'Args' in L<Catalyst::Controller> for more details on using
type constraints in your Args declarations.
package Catalyst::Exception::Basic;
-use MooseX::Role::WithOverloading;
+use Moose::Role;
+use if !eval { require Moose; Moose->VERSION('2.1300') },
+ 'MooseX::Role::WithOverloading';
use Carp;
use namespace::clean -except => 'meta';
package Catalyst::Exception::Interface;
-use MooseX::Role::WithOverloading;
+use Moose::Role;
+use if !eval { require Moose; Moose->VERSION('2.1300') },
+ 'MooseX::Role::WithOverloading';
use namespace::clean -except => 'meta';
use overload
use MooseX::Getopt;
use Catalyst::EngineLoader;
use Moose::Util::TypeConstraints;
-use Catalyst::Utils qw/ ensure_class_loaded /;
-use Class::Load 'load_class';
+use Catalyst::Utils;
use namespace::autoclean;
subtype 'Catalyst::ScriptRole::LoadableClass',
as 'ClassName';
coerce 'Catalyst::ScriptRole::LoadableClass',
from 'Str',
- via { ensure_class_loaded($_); 1 };
+ via { Catalyst::Utils::ensure_class_loaded($_); $_ };
with 'MooseX::Getopt' => {
-version => 0.48,
sub _run_application {
my $self = shift;
my $app = $self->application_name;
- load_class($app);
+ Catalyst::Utils::ensure_class_loaded($app);
my $server;
if (my $e = $self->_plack_engine_name ) {
$server = $self->load_engine($e, $self->_plack_loader_args);
--- /dev/null
+#!perl
+
+use strict;
+use warnings;
+use Test::More tests => 1;
+use HTTP::Request::Common;
+
+BEGIN {
+ package TestApp::Controller::Root;
+ $INC{'TestApp/Controller/Root.pm'} = __FILE__;
+ use Moose;
+ use MooseX::MethodAttributes;
+ extends 'Catalyst::Controller';
+
+ has counter => (is => 'rw', isa => 'Int', default => sub { 0 });
+ sub increment {
+ my $self = shift;
+ $self->counter($self->counter + 1);
+ }
+ sub root :Chained('/') :PathPart('') :CaptureArgs(0) {
+ my ($self, $c, $arg) = @_;
+ die "Died in root";
+ }
+ sub main :Chained('root') :PathPart('') :Args(0) {
+ my ($self, $c, $arg) = @_;
+ $self->increment;
+ die "Died in main";
+ }
+ sub hits :Path('hits') :Args(0) {
+ my ($self, $c, $arg) = @_;
+ $c->response->body($self->counter);
+ }
+ __PACKAGE__->config(namespace => '');
+}
+{
+ package TestApp;
+ $INC{'TestApp.pm'} = __FILE__;
+ use Catalyst;
+ __PACKAGE__->setup;
+}
+
+use Catalyst::Test 'TestApp';
+
+{
+ my $res = request('/');
+}
+{
+ my $res = request('/hits');
+ is $res->content, 0, "main action not touched on crash with no explicit setting";
+}
--- /dev/null
+#!perl
+
+use strict;
+use warnings;
+use Test::More tests => 1;
+use HTTP::Request::Common;
+
+BEGIN {
+ package TestApp::Controller::Root;
+ $INC{'TestApp/Controller/Root.pm'} = __FILE__;
+ use Moose;
+ use MooseX::MethodAttributes;
+ extends 'Catalyst::Controller';
+
+ has counter => (is => 'rw', isa => 'Int', default => sub { 0 });
+ sub increment {
+ my $self = shift;
+ $self->counter($self->counter + 1);
+ }
+ sub root :Chained('/') :PathPart('') :CaptureArgs(0) {
+ my ($self, $c, $arg) = @_;
+ die "Died in root";
+ }
+ sub main :Chained('root') :PathPart('') :Args(0) {
+ my ($self, $c, $arg) = @_;
+ $self->increment;
+ die "Died in main";
+ }
+ sub hits :Path('hits') :Args(0) {
+ my ($self, $c, $arg) = @_;
+ $c->response->body($self->counter);
+ }
+ __PACKAGE__->config(namespace => '');
+}
+{
+ package TestApp;
+ $INC{'TestApp.pm'} = __FILE__;
+ use Catalyst;
+ __PACKAGE__->config(abort_chain_on_error_fix => 1);
+ __PACKAGE__->setup;
+}
+
+use Catalyst::Test 'TestApp';
+
+{
+ my $res = request('/');
+}
+{
+ my $res = request('/hits');
+ is $res->content, 0, "main action not touched on crash with explicit setting to true";
+}
--- /dev/null
+#!perl
+
+use strict;
+use warnings;
+use Test::More tests => 1;
+use HTTP::Request::Common;
+
+BEGIN {
+ package TestApp::Controller::Root;
+ $INC{'TestApp/Controller/Root.pm'} = __FILE__;
+ use Moose;
+ use MooseX::MethodAttributes;
+ extends 'Catalyst::Controller';
+
+ has counter => (is => 'rw', isa => 'Int', default => sub { 0 });
+ sub increment {
+ my $self = shift;
+ $self->counter($self->counter + 1);
+ }
+ sub root :Chained('/') :PathPart('') :CaptureArgs(0) {
+ my ($self, $c, $arg) = @_;
+ die "Died in root";
+ }
+ sub main :Chained('root') :PathPart('') :Args(0) {
+ my ($self, $c, $arg) = @_;
+ $self->increment;
+ die "Died in main";
+ }
+ sub hits :Path('hits') :Args(0) {
+ my ($self, $c, $arg) = @_;
+ $c->response->body($self->counter);
+ }
+ __PACKAGE__->config(namespace => '');
+}
+{
+ package TestApp;
+ $INC{'TestApp.pm'} = __FILE__;
+ use Catalyst;
+ __PACKAGE__->config(abort_chain_on_error_fix => 0);
+ __PACKAGE__->setup;
+}
+
+use Catalyst::Test 'TestApp';
+
+{
+ my $res = request('/');
+}
+{
+ my $res = request('/hits');
+ is $res->content, 1, "main action performed on crash with explicit setting to false";
+}