Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Ruby SFTP example syntax error

I have an issue that seems like very flaky behavour, is this a problem with Ruby or something I've done? Please help - my project is stalled until I resolve this.

Given this code running on Mac OS Leopard:

require 'uri'
require 'net/ssh'
require 'net/sftp'
include Net

def copy_from_uri( uri, local_path )
    # SFTP copy
    SFTP.start( uri.host, uri.user, :password => 'password' ) do |sftp|
        puts "downloading from #{uri.host}, path #{uri.path}\n"
        sftp.download( uri.path, local_path )
    end
end

remote_uri = URI.parse( "sftp://example.com/test.mp4" )
local_file = "/tmp/remote_copy_test.mp4"
result = copy_from_uri( remote_uri, local_file );

What would cause the following error?

$ ruby sftp_fail.rb 
/Library/Ruby/Site/1.8/net/sftp.rb:43:in `start': undefined method `shutdown!' 
for nil:NilClass (NoMethodError)
    from sftp_fail.rb:8:in `copy_from_uri'
    from sftp_fail.rb:18

FYI I've set RUBYOPT correctly so gems are loaded and my gems are up-to-date, according to:

$gem list --local
net-sftp (2.0.2, 1.1.0)
net-ssh (2.0.15, 1.1.2)
like image 375
Justicle Avatar asked Jun 18 '26 16:06

Justicle


2 Answers

It is telling you that some object which you are attempting to call the shutdown! method on is nil. Now, that code is not in your example, so it is hard to say why that would be, but I highly doubt it is a bug in the language.

It is happening in this method call, so perhaps you can post that code?

result = copy_from_uri( remote_uri, local_file );

URI#parse should never return nil (it would throw an exception), so it would help to see that method body if possible.

like image 67
Ed S. Avatar answered Jun 21 '26 05:06

Ed S.


This error is actually due to a bug in net-sftp v2.0.2:

def self.start(host, user, options={}, &block)
  # ...
rescue Object => anything
  begin
    session.shutdown!
  rescue Exception
    # swallow exceptions that occur while trying to shutdown
  end

  raise anything
end

When an error occurs in the #start method, it attempts to shutdown the session...but if session itself is nil, it'll raise NoMethodError. The rescue Exception line attempts to swallow all exceptions but it is actually rescuing Net::SFTP::Exception rather than the root-level Exception. This has been recently fixed (see this commit).

Upgrade to net-sftp 2.0.4 and you'll no longer get this obscure error. You'll still get an error, but it should be more helpful now that the original error isn't being discarded by a new error happening in a rescue block.

like image 45
Myron Marston Avatar answered Jun 21 '26 06:06

Myron Marston



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!