Skip to content

send_error do not setup response code for hook callbacks #1229

@KES777

Description

@KES777

When we call send_error 418, { some => 'error' }

Next code is executed:

  1>203: sub send_error      { Dancer::Continuation::Route::ErrorSent->new(
    204:                           return_value => Dancer::Error->new(
    205:                               message => $_[0],
    206:                               code => $_[1] || 500)->render()
    207:                       )->throw }

Then this error is rendered (see line 206)

    191: sub render {
   x192:     my $self = shift;
    193:
   x194:     
   x195:     my $serializer = setting('serializer');
   x196:     Dancer::Factory::Hook->instance->execute_hooks('before_error_render', $self);
   x197:     my $response;
    198:     try {
 b4>199:         $response = $serializer ? $self->_render_serialized() : $self->_render_html();
    200:     } continuation {
 b x201:         my ($continuation) = @_;
    202:         # If we have a Route continuation, run the after hook, then
    203:         # propagate the continuation
   x204:         Dancer::Factory::Hook->instance->execute_hooks('after_error_render', $response);
   x205:         $continuation->rethrow();
  7>206:     };
 b x207:     Dancer::Factory::Hook->instance->execute_hooks('after_error_render', $response);
   x208:     $response;
    209: }

Here next subs are executed: before_error_render, _render_serialized

_render_serialized calls Dancer::Serializer->engine->serialize($message) in turn.

    211: sub _render_serialized {
   x212:     my $self = shift;
    213:
   x214:     
   x215:     my $message =
    216:       !ref $self->message ? {error => $self->message} : $self->message;
    217:
   x218:     if (ref $message eq 'HASH' && defined $self->exception) {
   x219:         if (blessed($self->exception)) {
   x220:             $message->{exception} = ref($self->exception);
   x221:             $message->{exception} =~ s/^Dancer::Exception:://;
    222:         } else {
   x223:             $message->{exception} = $self->exception;
    224:         }
    225:     }
    226:
   x227:     if (setting('show_errors')) {
  3>228:         Dancer::Response->new(
    229:             status  => $self->code, # <<< not in sync with Dancer::status # 200 != 418
    230:             content => Dancer::Serializer->engine->serialize($message),
    231:             headers => ['Content-Type' => Dancer::Serializer->engine->content_type]
    232:             );
    233:     }

both before_error_render and serialize are application subroutines, which may refer to Dancer::SharedData->response.
But this object is not in sync with http_code passed to send_error: 418 != 200

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions