Justicle
Justicle

Reputation: 15153

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)

Upvotes: 3

Views: 4312

Answers (3)

Mike
Mike

Reputation: 11

I've just encountered this, but it was caused by another reason. My file host had changed their RSA key, so the key in ~/.ssh/known_hosts was incorrect --- this resulted in the same error as shown, filtered up from SSH. Deleting the invalid key fixed the problem.

Upvotes: 1

Myron Marston
Myron Marston

Reputation: 21810

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.

Upvotes: 2

Ed Swangren
Ed Swangren

Reputation: 124652

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.

Upvotes: 3

Related Questions