Skip to content

Commit

Permalink
Rework halt to use with_return from Return::MultiLevel.
Browse files Browse the repository at this point in the history
Once #485 is merged, use the with_return handler to immediately stop processing
a before hook or route handler. Includes tests for use in a reoute handler and a
before hook.

Resolves #472.
  • Loading branch information
veryrusty authored and xsawyerx committed Dec 7, 2013
1 parent 09f7819 commit fa28401
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
15 changes: 15 additions & 0 deletions lib/Dancer2/Core/Context.pm
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,21 @@ sub redirect {
$self->with_return->($self->response) if $self->has_with_return;
}

=method halt
Flag the response object as 'halted'.
If called during request dispatch, immediatly returns the response
to the dispatcher and after hooks will not be run.
=cut

sub halt {
my ($self) = @_;
$self->response->halt;
# Short citcuit any remaining hook/route code
$self->with_return->($self->response) if $self->has_with_return;
}

=attr session
Expand Down
2 changes: 1 addition & 1 deletion lib/Dancer2/Core/DSL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ sub prefix {
: $app->lexical_prefix(@_);
}

sub halt { shift->app->context->response->halt }
sub halt { shift->app->context->halt }

sub _route_parameters {
my ( $regexp, $code, $options );
Expand Down
54 changes: 54 additions & 0 deletions t/dsl/halt.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use strict;
use warnings;

use Test::More;

subtest 'halt within routes' => sub {
{

package App;
use Dancer2;

get '/' => sub { 'hello' };
get '/halt' => sub {
header 'X-Foo' => 'foo';
halt;
};
get '/shortcircuit' => sub {
context->response->content('halted');
halt;
redirect '/'; # won't get executed as halt returns immediately.
};
}
use Dancer2::Test apps => ['App'];

response_status_is [ GET => '/shortcircuit' ] => 200;
response_content_is [ GET => '/shortcircuit' ] => "halted";

my $expected_headers = [
'X-Foo' => 'foo',
'Server' => "Perl Dancer2 $Dancer2::VERSION",
];
response_headers_include [ GET => '/halt' ] => $expected_headers;

};

subtest 'halt in before halt' => sub {
{
package App;
use Dancer2;

hook before => sub {
my $context = shift;
$context->response->content('I was halted');
halt if $context->request->dispatch_path eq '/shortcircuit';
};

}

response_status_is [ GET => '/shortcircuit' ] => 200;
response_content_is [ GET => '/shortcircuit' ] => "I was halted";

};

done_testing;

0 comments on commit fa28401

Please sign in to comment.