Skip to content

FileUtils.rm_rf should ignore only Errno::ENOENT, not StandardError#99

Merged
mame merged 3 commits intoruby:masterfrom
mame:dont-swallow-standarderror-in-fileutils-rm_rf
Aug 23, 2022
Merged

FileUtils.rm_rf should ignore only Errno::ENOENT, not StandardError#99
mame merged 3 commits intoruby:masterfrom
mame:dont-swallow-standarderror-in-fileutils-rm_rf

Conversation

@mame
Copy link
Member

@mame mame commented Jul 26, 2022

[Bug #18784]

mame and others added 3 commits July 26, 2022 21:38
The test was added for [Bug #6756]. The ticket insisted
`FileUtils.rm_rf` should delete an empty directory even if its
permission is 000. However, the test tried to delete a directory with
permission 700.
The ensure in postorder_traverse was added for [Bug #6756].
The intention was to try to delete the parent directory if it failed to
get the children. (It may be possible to delete the directory if it is
empty.)

However, the ensure region rescue'ed not only "failure to get children"
but also "failure to delete each child". Thus, the following raised
Errno::ENOTEMPTY, but we expect it to raise Errno::EACCES.

```
$ mkdir foo
$ touch foo/bar
$ chmod 555 foo
$ ruby -rfileutils -e 'FileUtils.rm_rf("foo")'
```

This changeset narrows the ensure region so that it rescues only
"failure to get children".
... instead of any StandardError.

To behave like the standard `rm` command, it should only ignore
exceptions about not existing files, not every exception. This should
make debugging some errors easier, because the expectation is that `rm
-rf` will succeed if and only if, all given files (previously existent
or not) are removed. However, due to this exception swallowing, this is
not always the case.

From the `rm` man page

> COMPATIBILITY
>
> The rm utility differs from historical implementations in that the -f
> option only masks attempts to remove non-existent files instead of
> masking a large variety of errors.

Co-Authored-By: David Rodríguez <deivid.rodriguez@riseup.net>
@deivid-rodriguez
Copy link
Contributor

Thanks a lot for this @mame!

This change is very useful for me. Not only fa65d67, but also ec5d3b8.

With ec5d3b8, an error like the one I got reported at ruby/rubygems#5274 will go from a

Directory not empty @ dir_s_rmdir - C:/Users/Alexandr.Evstigneev/.gem/ruby/3.0.0/gems/strscan-3.0.1

error to an Errno::EACCES error while trying to delete a specific .so file, which was the real culprit and so way more helpful!

@mame
Copy link
Member Author

mame commented Aug 23, 2022

I talked with @aamine, the original author of fileutils, about this change. He was a little concerned about the incompatibility but did not seem to strongly object.

https://twitter.com/mineroaoki/status/1555181426722881537

Please let me try this change once. If anyone reports practical problems with this change, I will be responsive to address them (including revert) on a best-effort basis.

@mame mame merged commit edd8d3b into ruby:master Aug 23, 2022
@eregon
Copy link
Member

eregon commented Aug 23, 2022

Great, thank you!

@aamine
Copy link

aamine commented Aug 24, 2022

Great work, thanks!

k0kubun added a commit to ruby/ruby that referenced this pull request Aug 27, 2022
@mame mame deleted the dont-swallow-standarderror-in-fileutils-rm_rf branch November 7, 2022 11:24
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.

4 participants