Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Handle exceptions from BEGIN blocks better.
We now include details of where the BEGIN block was in the code, the
fact that the error occurred while evaluating a BEGIN block, and a
stack trace inside of the BEGIN block. The mechanism will also be
useful for improving errors from the MOP (which we'll not show the
stack trace for) and other things like constants.
  • Loading branch information
jnthn committed Apr 8, 2015
1 parent 8337d80 commit abed501
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/Perl6/World.nqp
Expand Up @@ -2137,7 +2137,7 @@ class Perl6::World is HLL::World {
method add_phaser($/, $phaser, $block, $phaser_past?) {
if $phaser eq 'BEGIN' {
# BEGIN phasers get run immediately.
my $result := $block();
my $result := self.handle-begin-time-exceptions($/, 'evaluating a BEGIN', $block);
return self.add_constant_folded_result($result);
}
elsif $phaser eq 'CHECK' {
Expand Down Expand Up @@ -3097,6 +3097,41 @@ class Perl6::World is HLL::World {
}
}

method handle-begin-time-exceptions($/, $use-case, $code) {
my $ex;
my int $nok;
try {
return $code();
CATCH { $ex := $_; }
}

my int $success := 0;
my $coercer;
try { $coercer := self.find_symbol(['&COMP_EXCEPTION']); ++$success; };
nqp::rethrow($ex) unless $success;
my $p6ex := $coercer($ex);

my int $found_xcbt := 0;
my $x_comp_bt;
try {
$x_comp_bt := self.find_symbol(['X', 'Comp', 'BeginTime']);
$found_xcbt++;
}
if $found_xcbt {
my $xcbt := $x_comp_bt.new(exception => $p6ex, :$use-case);
$xcbt.SET_FILE_LINE(
nqp::box_s(nqp::getlexdyn('$?FILES'),
self.find_symbol(['Str'])),
nqp::box_i(HLL::Compiler.lineof($/.orig, $/.from, :cache(1)),
self.find_symbol(['Int'])),
);
$xcbt.throw;
}
else {
self.rethrow($/, $ex);
}
}

method rethrow($/, $err) {
my int $success := 0;
my $coercer;
Expand Down
1 change: 1 addition & 0 deletions src/core/Backtrace.pm
Expand Up @@ -72,6 +72,7 @@ my class Backtrace is List {
$file eq 'gen\\moar\\stage2\\NQPHLL.nqp';
my $subname = nqp::p6box_s(nqp::getcodename($sub));
$subname = '<anon>' if substr($subname,0, 6) eq '_block';
last if $subname eq 'handle-begin-time-exceptions';
$new.push: Backtrace::Frame.new(
:line($line.Int),
:$file,
Expand Down
26 changes: 26 additions & 0 deletions src/core/Exception.pm
Expand Up @@ -450,6 +450,32 @@ my class X::Comp::Group is Exception {

my role X::MOP is Exception { }

my class X::Comp::BeginTime does X::Comp {
has $.use-case;
has $.exception;

method message() {
$!exception ~~ X::MOP
?? $!exception.message
!! "An exception occurred while $!use-case"
}

multi method gist(::?CLASS:D: :$sorry = True) {
my $r = $sorry ?? self.sorry_heading() !! "";
$r ~= "$.message\nat $.filename():$.line";
for @.modules.reverse[1..*] {
my $line = nqp::p6box_i($_<line>);
$r ~= $_<module>.defined
?? "\n from module $_<module> ($_<filename>:$line)"
!! "\n from $_<filename>:$line";
}
unless $!exception ~~ X::MOP {
$r ~= "\nException details:\n" ~ $!exception.gist.indent(2);
}
$r;
}
}

# XXX a hack for getting line numbers from exceptions from the metamodel
my class X::Comp::AdHoc is X::AdHoc does X::Comp {
method is-compile-time() { True }
Expand Down

0 comments on commit abed501

Please sign in to comment.