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

VCR + excon does not work on Connection refused/DNS lookup failed #711

Open
perlun opened this issue May 30, 2018 · 5 comments
Open

VCR + excon does not work on Connection refused/DNS lookup failed #711

perlun opened this issue May 30, 2018 · 5 comments

Comments

@perlun
Copy link
Contributor

perlun commented May 30, 2018

I noted this when trying to use VCR for a use case where I'm querying a bunch of local ports, some of which reply and others which return a Connection refused. This seems to trigger various exceptions in VCR.

I've nailed it down to a test case like this now (foo_bar is obviously a non-existing domain name):

require 'test/unit'
require 'excon'
require 'vcr'

VCR.configure do |config|
  config.cassette_library_dir = "fixtures/vcr_cassettes"
  config.hook_into :excon
end

class VCRTest < Test::Unit::TestCase
  def test_example_dot_com
    VCR.use_cassette("dummy") do
      response = Excon.get('http://foo_bar:8000/')
      assert_match /baz/, response.body
    end
  end
end

This fails with the following exception:

Loaded suite foo
Started
E
================================================================================================================================================================================================================================================
foo.rb:13:in `test_example_dot_com'
     10:
     11: class VCRTest < Test::Unit::TestCase
     12:   def test_example_dot_com
  => 13:     VCR.use_cassette("dummy") do
     14:       response = Excon.get('http://foo_bar:8000/')
     15:       assert_match /baz/, response.body
     16:     end
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr.rb:191:in `use_cassette'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr.rb:191:in `ensure in use_cassette'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr.rb:156:in `eject_cassette'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:65:in `eject'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:263:in `write_recorded_interactions_to_disk'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:118:in `serializable_hash'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:256:in `interactions_to_record'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:256:in `map'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:256:in `block in interactions_to_record'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/structs.rb:497:in `to_hash'
Error: test_example_dot_com(VCRTest): NoMethodError: undefined method `to_hash' for nil:NilClass
================================================================================================================================================================================================================================================

Finished in 6.053187 seconds.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 tests, 0 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0.17 tests/s, 0.00 assertions/s

If I add a config.debug_logger = $stdout inside the VCR.configure block, I get this error instead:

Loaded suite foo
Started
[Cassette: 'dummy'] Initialized with options: {:record=>:once, :match_requests_on=>[:method, :uri], :allow_unused_http_interactions=>true, :serialize_with=>:yaml, :persist_with=>:file_system}
[excon] Handling request: [get http://foo_bar:8000/] (disabled: false)
  [Cassette: 'dummy'] Initialized HTTPInteractionList with request matchers [:method, :uri] and 0 interaction(s): {  }
[excon] Identified request type (recordable) for [get http://foo_bar:8000/]
E
================================================================================================================================================================================================================================================
foo.rb:13:in `test_example_dot_com'
     10:
     11: class VCRTest < Test::Unit::TestCase
     12:   def test_example_dot_com
  => 13:     VCR.use_cassette("dummy") do
     14:       response = Excon.get('http://foo_bar:8000/')
     15:       assert_match /baz/, response.body
     16:     end
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
foo.rb:14:in `block in test_example_dot_com'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/excon-0.62.0/lib/excon.rb:242:in `get'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/excon-0.62.0/lib/excon/connection.rb:225:in `request'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/excon-0.62.0/lib/excon/connection.rb:283:in `rescue in request'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/excon-0.62.0/lib/excon/middlewares/base.rb:11:in `error_call'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:38:in `error_call'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:46:in `complete_request'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:78:in `after_request'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr.rb:344:in `record_http_interaction'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:84:in `record_http_interaction'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:84:in `synchronize'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/cassette.rb:85:in `block in record_http_interaction'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/util/logger.rb:55:in `response_summary'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-3.0.3/lib/vcr/util/logger.rb:23:in `response_summary'
Error: test_example_dot_com(VCRTest): NoMethodError: undefined method `status' for nil:NilClass
================================================================================================================================================================================================================================================

Finished in 0.057659 seconds.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 tests, 0 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
17.34 tests/s, 0.00 assertions/s

Any ideas on how to resolve this, is this an unsupported scenario? I was hoping to be able to use VCR to record these transactions to have a solid spec for my REST API (which queries a dynamic list of microservices to return its data.)

@perlun
Copy link
Contributor Author

perlun commented May 30, 2018

Update: If I switch to use Net::HTTP instead, it actually works (no error):

require 'test/unit'
require 'vcr'

VCR.configure do |config|
  config.cassette_library_dir = "fixtures/vcr_cassettes"
  config.hook_into :webmock
end

class VCRTest < Test::Unit::TestCase
  def test_example_dot_com
    VCR.use_cassette("dummy") do
      response = Net::HTTP.get_response(URI('http://foo_bar:8000/'))
      assert_match /baz/, response.body
    rescue SocketError
      # Ignore errors
    end
  end
end

My real-world use case (which got me started investigating this in the first place) has similar exception handling (for excon) in place. My guess would be that VCR doesn't handle exceptions in excon the proper way somehow.

Anyway, I think I'll resort to use Net::HTTP for now, my use case is rather trivial so it's probably simple for me to change to Net::HTTP. Nonetheless, I think it might make sense to keep this issue open since other people could run into this also and it would be great to get it fixed in the gem.

@krainboltgreene
Copy link
Contributor

This is absolutely supported, I use VCR to prevent connections between my containers. Hmm.

@krainboltgreene
Copy link
Contributor

Can you upgrade to v4?

@perlun
Copy link
Contributor Author

perlun commented May 31, 2018

Can you upgrade to v4?

Sure, tried that now - same issue:

$ ruby foo.rb
Loaded suite foo
Started
E
==================================================================================================================================================================================================================================================
foo.rb:12:in `test_example_dot_com'
      9:
     10: class VCRTest < Test::Unit::TestCase
     11:   def test_example_dot_com
  => 12:     VCR.use_cassette("dummy") do
     13:       response = Excon.get('http://foo_bar:8000/')
     14:       assert_match /baz/, response.body
     15:     end
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr.rb:190:in `use_cassette'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr.rb:190:in `ensure in use_cassette'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr.rb:155:in `eject_cassette'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr/cassette.rb:68:in `eject'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr/cassette.rb:271:in `write_recorded_interactions_to_disk'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr/cassette.rb:121:in `serializable_hash'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr/cassette.rb:264:in `interactions_to_record'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr/cassette.rb:264:in `map'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr/cassette.rb:264:in `block in interactions_to_record'
/Users/plundberg/.rvm/gems/ruby-2.5.1/gems/vcr-4.0.0/lib/vcr/structs.rb:497:in `to_hash'
Error: test_example_dot_com(VCRTest): NoMethodError: undefined method `to_hash' for nil:NilClass
==================================================================================================================================================================================================================================================

Finished in 0.133345 seconds.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 tests, 0 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7.50 tests/s, 0.00 assertions/s

@andrehjr
Copy link
Contributor

andrehjr commented Jan 2, 2022

I believe this was fixed by #916

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

No branches or pull requests

3 participants