Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement file parsing error handling #2365

Merged
merged 1 commit into from
Feb 6, 2024

Conversation

eileencodes
Copy link
Member

@eileencodes eileencodes commented Feb 5, 2024

Implement file parsing error handling

This PR implements proper file parsing error handling. Previously
file_options would call pm_string_mapped_init which would print an
error from perror. However this wouldn't raise a proper Ruby error so
it was just a string output. I've done the following:

  • Raise an error from rb_syserr_fail with the filepath in
    file_options.
  • No longer return Qnil if file_options returns false (because now
    it will raise)
  • Update file_options to return static void instead of static bool.
  • Update file_options and profile_file to check the type so when
    passing nil we see a TypeError.
  • Delete perror from pm_string_mapped_init
  • Update FFI backend to raise appropriate errors when calling
    pm_string_mapped_init.
  • Add tests for dump_file, lex_file, parse_file,
    parse_file_comments, parse_lex_file, and parse_file_success?,
    when a file doesn't exist and for nil.
  • Updates the bin/parse script to no longer raise it's own
    ArgumentError now that we raise a proper error.

Fixes: #2207

@eileencodes
Copy link
Member Author

Oops, forgot to run all the tests. Will update.

Copy link
Collaborator

@kddnewton kddnewton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@kddnewton
Copy link
Collaborator

Looks like the windows tests are failing because it's a different errno error (I think that's expected). Can you check for a superclass?

@kddnewton
Copy link
Collaborator

Ahh it looks like FFI is failing because it needs to be updated. You can check that with:

PRISM_FFI_BACKEND=1 bundle exec rake

@eileencodes
Copy link
Member Author

I'm a little bit stuck. FFI tests are failing because we check LibRubyParser.pm_string_mapped_init and raise if it's false.

raise unless LibRubyParser.pm_string_mapped_init(pointer, filepath)

I can't figure out how (or even if) I can get the errno here in order to raise a SystemCallError.new(filepath, ????) with the right error code. The errno is different for nil or doesn't exist, so I can't pass in the Errno::ENOENT constant.

@eileencodes
Copy link
Member Author

After pairing with Kevin (thank you!) we've changed pm_string_mapped_init to return the error code instead of a boolean so we can raise an appropriate SystemCallError from FFI.

@eileencodes eileencodes force-pushed the implement-prism-2207 branch 3 times, most recently from 92642f2 to b8cb050 Compare February 6, 2024 16:43
@eregon
Copy link
Member

eregon commented Feb 6, 2024

FWIW there is FFI.errno to get the errno.
That's fully reliable if the previous call was a call done with FFI (i.e. it's properly saved&restored around FFI calls and not just accessing the native errno).

Comment on lines 83 to 87
error = assert_raise Errno::EFAULT do
Prism.dump_file(nil)
end

assert_equal "Bad address", error.message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a bit strange that nil would raise EFAULT.
I would expect a coercion error, just like File.read does:

$ ruby -e 'File.read nil'
-e:1:in `read': no implicit conversion of nil into String (TypeError)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now raising a TypeError.

@eileencodes eileencodes force-pushed the implement-prism-2207 branch 11 times, most recently from 42d53f8 to bb75713 Compare February 6, 2024 20:15
end
end

def test_profile_file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one you should remove, because it's not implemented in the FFI. We'll trust that it'll work since it's not supposed to be exposed anyway. But thank you for being thorough!

This PR implements proper file parsing error handling. Previously
`file_options` would call `pm_string_mapped_init` which would print an
error from `perror`. However this wouldn't raise a proper Ruby error so
it was just a string output. I've done the following:

- Raise an error from `rb_syserr_fail` with the filepath in
`file_options`.
- No longer return `Qnil` if `file_options` returns false (because now
it will raise)
- Update `file_options` to return `static void` instead of `static
bool`.
- Update `file_options` and `profile_file` to check the type so when
passing `nil` we see a `TypeError`.
- Delete `perror` from `pm_string_mapped_init`
- Update `FFI` backend to raise appropriate errors when calling
`pm_string_mapped_init`.
- Add tests for `dump_file`, `lex_file`, `parse_file`,
`parse_file_comments`, `parse_lex_file`, and `parse_file_success?`
when a file doesn't exist and for `nil`.
- Updates the `bin/parse` script to no longer raise it's own
`ArgumentError` now that we raise a proper error.

Fixes: ruby#2207
@eileencodes
Copy link
Member Author

Ok I think this is ready now! 😄

Copy link
Collaborator

@kddnewton kddnewton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job!

@kddnewton kddnewton merged commit 5cd031d into ruby:main Feb 6, 2024
48 checks passed
@eileencodes eileencodes deleted the implement-prism-2207 branch February 6, 2024 22:13
eileencodes added a commit to eileencodes/ruby that referenced this pull request Feb 6, 2024
Following changes made in ruby/prism#2365 this implements error handling
for when `pm_string_mapped_init` returns `false`.

Related: ruby/prism#2207
eileencodes added a commit to eileencodes/ruby that referenced this pull request Feb 7, 2024
Following changes made in ruby/prism#2365 this implements error handling
for when `pm_string_mapped_init` returns `false`.

Related: ruby/prism#2207
kddnewton pushed a commit to ruby/ruby that referenced this pull request Feb 11, 2024
Following changes made in ruby/prism#2365 this implements error handling
for when `pm_string_mapped_init` returns `false`.

Related: ruby/prism#2207
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Prism::parse_file* APIs should raise appropriate errors
3 participants