Skip to content

Instantly share code, notes, and snippets.

@teancom
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teancom/137440924c79f85727d0 to your computer and use it in GitHub Desktop.
Save teancom/137440924c79f85727d0 to your computer and use it in GitHub Desktop.
make sure file exists before writing to it
if options.has_key? :file then
file = options[:file]
dir = File.dirname(file)
if File.directory?(dir) && File.writable?(dir) then
if File.exists?(file) && ! File.writable?(file) then
abort "Can't write to file. No permission?"
else
$stdout = File.new file, 'w'
end
else
abort "Can't write to directory. No permission?"
end
end
@wdomburg
Copy link

This would capture all the potential error cases and provide the default error message for each case.

if options.has_key? :file then
    path = options[:file]
    begin
        $stdout.reopen(path, 'a')
    rescue => e
        abort e.message
    end
end

It won't give a different error for an unwriteable file or unwriteable directory, but you could provide this by handling Errno::EACCES explicitly; e.g.

if options.has_key? :file then
    path = options[:file]
    begin
        $stdout.reopen(path, 'a')
    rescue Errono::EACCES=> e
        dir = File.dirname(path)
        abort File.writable?(dir) ? "Can't write to directory.  No permission." : "Can't write to file. No Permission."
    rescue => e
        abort e.message
    end
end

@wdomburg
Copy link

Err, flip the error messages around in that ternary. :)

@teancom
Copy link
Author

teancom commented Jun 17, 2014

Before refreshing the page and seeing your solution, I took your advice from twitter and did the following:

if options.has_key? :file then
  begin
    $stdout.reopen(options[:file], 'w')
  rescue Errno::ENOENT => e
    abort "Can't write into that directory. Does it exist?"
  rescue Errno::EACCES => e
    abort "Can't write to file or directory. Do you have permission?"
  rescue Errno::EISDIR => e
    abort "Please pass in a file name, not a directory name."
  rescue => e
    abort e.message
  end
end

But I like your solution even better. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment