Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
A Failure that throws counts as handled.
This means fatalized Failures will not report themselves as leaked.
  • Loading branch information
jnthn committed Jun 9, 2015
1 parent 70abc0b commit 80f8efc
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions src/core/Failure.pm
Expand Up @@ -14,6 +14,12 @@ my class Failure {
# "Shouldn't happen." We use note here because the dynamic scope in GC is likely meaningless.
submethod DESTROY () { if not $!handled { note "WARNING: unhandled Failure detected in DESTROY:\n" ~ self.mess } }

# Marks the Failure has handled (since we're now fatalizing it) and throws.
method !throw() {
$!handled = 1;
$!exception.throw($!backtrace);
}

# Turns out multidimensional lookups are one way to leak unhandled failures, so
# we'll just propagate the initial failure much as we propagate Nil on methods.
method AT-POS(|) { self }
Expand All @@ -23,28 +29,28 @@ my class Failure {
# but obscure problems prevent us from making Mu.defined
# a multi. See http://irclog.perlgeek.de/perl6/2011-06-28#i_4016747
method defined() {
$!handled =1 if nqp::isconcrete(self);
$!handled = 1 if nqp::isconcrete(self);
Bool::False;
}
multi method Bool(Failure:D:) { $!handled = 1; Bool::False; }

method Int(Failure:D:) { $!handled ?? 0 !! $!exception.throw($!backtrace); }
method Num(Failure:D:) { $!handled ?? 0e0 !! $!exception.throw($!backtrace); }
method Numeric(Failure:D:) { $!handled ?? 0e0 !! $!exception.throw($!backtrace); }
multi method Str(Failure:D:) { $!handled ?? '' !! $!exception.throw($!backtrace); }
multi method gist(Failure:D:) { $!handled ?? $.mess !! $!exception.throw($!backtrace); }
method Int(Failure:D:) { $!handled ?? 0 !! self!throw(); }
method Num(Failure:D:) { $!handled ?? 0e0 !! self!throw(); }
method Numeric(Failure:D:) { $!handled ?? 0e0 !! self!throw(); }
multi method Str(Failure:D:) { $!handled ?? '' !! self!throw(); }
multi method gist(Failure:D:) { $!handled ?? $.mess !! self!throw(); }
method mess (Failure:D:) {
self.exception.message ~ "\n" ~ self.backtrace;
}

method sink() {
$!exception.throw($!backtrace) unless $!handled
self!throw() unless $!handled
}
method CALL-ME(|) {
$!exception.throw($!backtrace)
self!throw()
}
method FALLBACK(*@) {
$!exception.throw($!backtrace)
self!throw()
}
}

Expand Down

0 comments on commit 80f8efc

Please sign in to comment.