Skip to content

Commit

Permalink
pass, redirect, forward, halt, send_error, send_file, template now in…
Browse files Browse the repository at this point in the history
…tterupt route workflows (no need to return)
  • Loading branch information
dams committed Oct 17, 2011
1 parent 6066a9e commit 45e52a8
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 8 deletions.
25 changes: 21 additions & 4 deletions lib/Dancer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ use Dancer::SharedData;
use Dancer::Handler;
use Dancer::MIME;

use Dancer::Continuation::Halted;
use Dancer::Continuation::Route::Forwarded;
use Dancer::Continuation::Route::Passed;
use Dancer::Continuation::Route::ErrorSent;
use Dancer::Continuation::Route::FileSent;
use Dancer::Continuation::Route::Templated;

use File::Spec;

Expand Down Expand Up @@ -127,7 +131,10 @@ sub from_json { Dancer::Serializer::JSON::from_json(@_) }
sub from_xml { Dancer::Serializer::XML::from_xml(@_) }
sub from_yaml { Dancer::Serializer::YAML::from_yaml(@_) }
sub get { map { my $r = $_; Dancer::App->current->registry->universal_add($r, @_) } qw(head get) }
sub halt { Dancer::SharedData->response->halt(@_) }
sub halt { Dancer::SharedData->response->halt(@_);
# throw a special continuation exception
Dancer::Continuation::Halted->new->throw;
}
sub header { goto &headers }
sub push_header { Dancer::SharedData->response->push_header(@_); }
sub headers { Dancer::SharedData->response->headers(@_); }
Expand Down Expand Up @@ -158,16 +165,26 @@ sub put { Dancer::App->current->registry->universal_add('put', @
sub redirect { goto &_redirect }
sub render_with_layout { Dancer::Template::Abstract->_render_with_layout(@_) }
sub request { Dancer::SharedData->request }
sub send_error { Dancer::Error->new(message => $_[0], code => $_[1] || 500)->render() }
sub send_file { goto &_send_file }
sub send_error { Dancer::Continuation::Route::ErrorSent->new(
return_value => Dancer::Error->new(
message => $_[0],
code => $_[1] || 500)->render()
)->throw }
#sub send_file { goto &_send_file }
sub send_file { Dancer::Continuation::Route::FileSent->new(
return_value => _send_file(@_)
)->throw
}
sub set { goto &setting }
sub set_cookie { Dancer::Cookies->set_cookie(@_) }
sub setting { Dancer::App->applications ? Dancer::App->current->setting(@_) : Dancer::Config::setting(@_) }
sub session { goto &_session }
sub splat { @{ Dancer::SharedData->request->params->{splat} || [] } }
sub start { goto &_start }
sub status { Dancer::SharedData->response->status(@_) }
sub template { Dancer::Template::Abstract->template(@_) }
sub template { Dancer::Continuation::Route::Templated->new(
return_value => Dancer::Template::Abstract->template(@_)
)->throw }
sub to_dumper { Dancer::Serializer::Dumper::to_dumper(@_) }
sub to_json { Dancer::Serializer::JSON::to_json(@_) }
sub to_xml { Dancer::Serializer::XML::to_xml(@_) }
Expand Down
5 changes: 4 additions & 1 deletion lib/Dancer/Continuation.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use strict;
use warnings;
use Carp;

sub new { bless {}, shift }
sub new {
my $class = shift;
bless { @_ }, $class;
}

sub throw { die shift }

Expand Down
8 changes: 8 additions & 0 deletions lib/Dancer/Continuation/Route.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,12 @@ use Carp;

use base qw(Dancer::Continuation);

# A Dancer::Continuation::Route is a continuation exception, that is caught as
# route execution level (see Dancer::Route::run). It may store a return_value, that
# will be recovered from the continuation catcher, and stored as the returning
# content.

sub return_value { $#_ ? $_[0]->{return_value} = $_[1] : $_[0]->{return_value} }


1;
9 changes: 9 additions & 0 deletions lib/Dancer/Continuation/Route/ErrorSent.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package Dancer::Continuation::Route::ErrorSent;

use strict;
use warnings;
use Carp;

use base qw(Dancer::Continuation::Route);

1;
9 changes: 9 additions & 0 deletions lib/Dancer/Continuation/Route/FileSent.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package Dancer::Continuation::Route::FileSent;

use strict;
use warnings;
use Carp;

use base qw(Dancer::Continuation::Route);

1;
9 changes: 9 additions & 0 deletions lib/Dancer/Continuation/Route/Templated.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package Dancer::Continuation::Route::Templated;

use strict;
use warnings;
use Carp;

use base qw(Dancer::Continuation::Route);

1;
2 changes: 0 additions & 2 deletions lib/Dancer/Response.pm
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ sub halt {
halted => 1,
);
}
# throw a special continuation exception
Dancer::Continuation::Halted->new->throw;
}

sub halted {
Expand Down
5 changes: 5 additions & 0 deletions lib/Dancer/Route.pm
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,13 @@ sub run {
# route related continuation
$continuation->isa('Dancer::Continuation::Route')
or $continuation->rethrow();
# If the continuation carries some content, get it
my $content = $continuation->return_value();
defined $content or return; # to avoid returning undef;
return $content;
} catch {
my ($exception) = @_;
# all other exceptions (dancer or not) are rethrown
die $exception;
};
my $response = Dancer::SharedData->response;
Expand Down
4 changes: 3 additions & 1 deletion t/03_route_handler/03_routes_api.t
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ is $response->{content} => 42, "response looks good";

my $r2 = Dancer::Route->new(method => 'get',
pattern => '/pass/:var',
code => sub { pass && "this is r2" },
code => sub { pass;
# The next line is not executed, as 'pass' breaks the route workflow
die },
prev => $r);

my $r3 = Dancer::Route->new(method => 'get',
Expand Down
2 changes: 2 additions & 0 deletions t/06_helpers/01_send_file.t
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ plan tests => 20;

get '/cat/:file' => sub {
send_file(params->{file});
# The next line is not executed, as 'send_error' breaks the route workflow
die;
};

get '/catheader/:file' => sub {
Expand Down
2 changes: 2 additions & 0 deletions t/06_helpers/05_send_error.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ set show_errors => 1;

get '/error' => sub {
send_error "FAIL";
# The next line is not executed, as 'send_error' breaks the route workflow
die;
};

response_status_is [GET => '/error'] => 500,
Expand Down

0 comments on commit 45e52a8

Please sign in to comment.