perldancer

Why Dancer `halt` command bypass all events?


Example:

hook on_route_exception => sub {
    # This code is not executed  
}

hook on_handler_exception => sub {
    # This code is not executed  
}

hook after => sub {
    # This code is not executed  
}


hook after_error_render => sub {
    # This code is not executed  
}

hook before => sub {
    if ($some_condition) {
        halt("Unauthorized");
        # This code is not executed :
        do_stuff();
    }
};
 
get '/' => sub {
    "hello there";
};

I can find this piece of documentation:

Thus, any code after a halt is ignored, until the end of the route.

But hooks are after the end of route, so should not be ignored. Should be?

Why hooks are ignored too?


Solution

  • I would think that the reason is that the processing was halted. The

    halt("Unauthorized");
    

    would essentially return that content in the response object and no further events are required. The halt effectively halted all processing for that request/response.

    That is a guess based on how it is behaving and the description.

    A closer look at :https://metacpan.org/release/BIGPRESH/Dancer-1.3513/source/lib/Dancer.pm#L156

    shows that after the Response Content is set to "Unauthorized" it calls:

    Dancer::Continuation::Halted->new->throw
    

    which dies:

    https://metacpan.org/release/BIGPRESH/Dancer-1.3513/source/lib/Dancer/Continuation.pm#L14

    sub throw { die shift }
    

    At least that's how I read that code. Since it dies there is nothing else to do.

    Likely a deliberate design decision based on the intention to halt.