Truffleruby: "Rescuing" failed `require` doesn't work as expected

Created on 13 Jul 2020  路  12Comments  路  Source: oracle/truffleruby

Context

In Ruby Next, I want to be able to "catch" syntax errors occurred while requiring a file to transpile this file on-the-fly and evaluate (ruby -ruby-next some_ruby_file_with_edge_syntax.rb, see uby-next.rb).

Problem

To make this work I use at_exit hook and check whether $! is a SyntaxError, try to re-load the transpiled version and call exit!(0) if that works.

In TruffleRuby, at_exit block is called, we can access the exception via $! but calling exit!(0) has no effect鈥攖he exit status is still >0.
Also, the exception message is printed as well (in MRI, if we "caught" the exception, there is no err output).

Here is the minimal reproduction: https://github.com/palkan/ruby-compatibility-examples/blob/master/examples/at_exit_rescue.rb

And here is the failing CI build with the output: https://github.com/palkan/ruby-compatibility-examples/runs/864905161?check_suite_focus=true

P.S. There you can find how MRI and JRuby handle this. (JRuby sets the correct exit status but still prints the error message).

/cc @ssnickolay

compatibility

All 12 comments

try to re-load the transpiled version and call exit!(0) if that works.

I don't understand this bit - if you can successfully transpile and reload... you then exit? Why don't you then keep going with the transpiled code?

The exit!(0) is a way to suppress the original SyntaxError, which would otherwise be shown.

But the exit!(0) doesn't actually cause the process to exit? I thought after transpiling you'd want to continue?

I've tested locally and didn't see the error (note: the TR build includes not released fix for refine_include_super.rb):

Screenshot 2020-07-13 at 16 00 00

p.s. for JRuby I see described behaviour (print error stack trace but correct exit status)

SyntaxError: /Users/ssnickolay/Projects/oss/ruby-compatibility-examples/support/invalid_syntax.rb:1: syntax error, unexpected '}'
invalid_hash = {x: }
                   ^
           require at org/jruby/RubyKernel.java:974
  require_relative at org/jruby/RubyKernel.java:1002
            <main> at examples/at_exit_rescue.rb:8
We catched it!

@ssnickolay https://github.com/palkan/ruby-compatibility-examples/blob/master/run-all.rb assumes you're running with the ruby to test in PATH.

I can reproduce on master, I'm working on a fix.

assumes you're running with the ruby to test in PATH.

Yeah, I didn't read carefully run-all.rb

Fixed in e9dce4a8d216454de7273fb3780a17c18a811574, thanks for the report and reproducer!

Sorry, but I broke it again 馃檭

Here is a bit more complex example: https://github.com/palkan/ruby-compatibility-examples/commit/f92c69c0366e1c3b656d2ef7aead4a1a79bb5c0b (and the corresponding CI build: https://github.com/palkan/ruby-compatibility-examples/runs/884982846?check_suite_focus=true).

This time, we define at_exit hook in the required file (-r), not the one we execute. That could be the reason.

P.S. I can open a new issue if you'd like.

I'll take a look, thanks for the reproducer :smiley:

Run examples/cli_require_at_exit.rb:  馃挜 truffleruby:
examples/../support/typo.rb:1: syntax error, unexpected tRCURLY (SyntaxError)
examples/cli_require_at_exit.rb:2:in `<main>': Assertion failed:  (RuntimeError)

It seems the issue in that case is that the SyntaxError happens in the "main script file" and so before TruffleRuby enters TopLevelRaiseHandler.

That example is fixed with efa38abf2be8e55900f92259c56f90cda8f896bf.

Was this page helpful?
0 / 5 - 0 ratings