Dancer2

 view release on metacpan or  search on metacpan

t/error.t  view on Meta::CPAN


subtest 'Response->error()' => sub {
    my $resp = Dancer2::Core::Response->new;

    isa_ok $resp->error( message => 'oops', status => 418 ),
      'Dancer2::Core::Error';

    is $resp->status    => 418,        'response code is 418';
    like $resp->content => qr/oops/,   'response content overriden by error';
    like $resp->content => qr/teapot/, 'error code title is present';
    ok $resp->is_halted, 'response is halted';
};

subtest 'Throwing an error with a response' => sub {
    my $resp = Dancer2::Core::Response->new;

    my $err = eval { Dancer2::Core::Error->new(
        exception   => 'our exception',
        show_stacktrace => 1
    )->throw($resp) };
      
    isa_ok($err, 'Dancer2::Core::Response', "Error->throw() accepts a response");
};

subtest 'Error with show_stacktrace: 0' => sub {
    my $err = Dancer2::Core::Error->new(
        exception       => 'our exception',
        show_stacktrace => 0
    )->throw;
    unlike $err->content => qr/our exception/;
};

subtest 'Error with show_stacktrace: 1' => sub {
    my $err = Dancer2::Core::Error->new(
        exception       => 'our exception',
        show_stacktrace => 1
    )->throw;
    like $err->content => qr/our exception/;
};

subtest 'App dies with serialized error' => sub {
    {
        package AppDies;
        use Dancer2;
        set serializer => 'JSON';

        get '/die' => sub {
            die "oh no\n"; # I should serialize
        };
    }

    my $app = AppDies->to_app;
    isa_ok( $app, 'CODE', 'Got app' );

    test_psgi $app, sub {
        my $cb = shift;
        my $r  = $cb->( GET '/die' );

        is( $r->code, 500, '/die returns 500' );

        my $out = eval { JSON->new->utf8(0)->decode($r->decoded_content) };
        ok(!$@, 'JSON decoding serializer error produces no errors');
        isa_ok($out, 'HASH', 'Error deserializes to a hash');
        like($out->{exception}, qr/^oh no/, 'Get expected error message');
    };
};

subtest 'Error with exception object' => sub {
    local $@;
    eval { MyTestException->throw('a test exception object') };
    my $exception = $@;
    my $err = Dancer2::Core::Error->new(
        app             => Dancer2::Core::App->new(),
        exception       => $exception,
        show_stacktrace => 1,
    )->throw;

    like $err->content, qr/a test exception object/, 'Error content contains exception message';
};

subtest 'Errors without server tokens' => sub {
    {
        package AppNoServerTokens;
        use Dancer2;
        set serializer => 'JSON';
        set no_server_tokens => 1;

        get '/ohno' => sub {
            die "oh no";
        };
    }

    my $test = Plack::Test->create( AppNoServerTokens->to_app );
    my $r = $test->request( GET '/ohno' );
    is( $r->code, 500, "/ohno returned 500 response");
    is( $r->header('server'), undef, "No server header when no_server_tokens => 1" );
};

subtest 'Errors with show_stacktrace and circular references' => sub {
    {
        package App::ShowErrorsCircRef;
        use Dancer2;
        set show_stacktrace           => 1;
        set something_with_config => {something => config};
        set password              => '===VERY-UNIQUE-STRING===';
        set innocent_thing        => '===VERY-INNOCENT-STRING===';
        set template              => 'tiny';

        # Trigger an error that makes Dancer2::Core::Error::_censor enter an
        # infinite loop
        get '/ohno' => sub {
            template q{I don't exist};
        };

    }

    my $test = Plack::Test->create( App::ShowErrorsCircRef->to_app );
    my $r = $test->request( GET '/ohno' );
    is( $r->code, 500, "/ohno returned 500 response");
    like( $r->content, qr{Stack}, 'it includes a stack trace' );



( run in 0.739 second using v1.01-cache-2.11-cpan-39bf76dae61 )