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

Typhoeus return_message lost when creating a Webmock response #1057

Open
thebravoman opened this issue May 3, 2024 · 1 comment
Open

Typhoeus return_message lost when creating a Webmock response #1057

thebravoman opened this issue May 3, 2024 · 1 comment

Comments

@thebravoman
Copy link

thebravoman commented May 3, 2024

Send request to "http://post_zip.pixel/2"
This is invalid and typhoeus will return code:0 return_message: "Couldn't resolve host name"

This is lost when creating the webmock response

   78:           request_signature
   79:         end
   80: 
   81: 
   82:         def self.build_webmock_response(typhoeus_response)
=> 83:           webmock_response = WebMock::Response.new
   84:           webmock_response.status = [typhoeus_response.code, typhoeus_response.status_message]
   85:           webmock_response.body = typhoeus_response.body
   86:           webmock_response.headers = typhoeus_response.headers
   87:           webmock_response
(byebug) typhoeus_response
#<Typhoeus::Response:0x0000000112c8a920 @options={:httpauth_avail=>0, :total_time=>0.000744, :starttransfer_time=>0.0, :appconnect_time=>0.0, :pretransfer_time=>0.0, :connect_time=>0.0, :namelookup_time=>0.0, :redirect_time=>0.0, :effective_url=>"http://post_zip.pixel/2", :primary_ip=>"", :response_code=>0, :request_size=>0, :redirect_count=>0, :size_upload=>0.0, :size_download=>0.0, :speed_upload=>0.0, :speed_download=>0.0, :return_code=>:couldnt_resolve_host, :response_headers=>"", :response_body=>"", :debug_info=>#<Ethon::Easy::DebugInfo:0x0000000112c714c0 @messages=[]>}, @request=#<Typhoeus::Request:0x00000001220ed698 @base_url="http://post_zip.pixel/2", @original_options={:method=>"post", :timeout=>5}, @options={:method=>"post", :timeout=>5, :headers=>{"User-Agent"=>"RetreaverPinger/2.0 (+https://retreaver.com/bot)", "Expect"=>""}, :maxredirs=>50}, @on_complete=[#<Proc:0x00000001220ed418 /Users/kireto/axles/code/callpixels/lib/pinger_diversion.rb:213>], @__webmock_request_signature=#<WebMock::RequestSignature:0x00000001220f7558 @method=:post, @uri=#<Addressable::URI:0x4e46c URI:http://post_zip.pixel:80/2>, @body=nil, @headers={"User-Agent"=>"RetreaverPinger/2.0 (+https://retreaver.com/bot)", "Expect"=>""}, @__typed_vcr_request=#<struct VCR::Request method=:post, uri="http://post_zip.pixel/2", body="", headers={"User-Agent"=>["RetreaverPinger/2.0 (+https://retreaver.com/bot)"], "Expect"=>[""]}>>, @block_connection=false, @response=#<Typhoeus::Response:0x0000000112c8a920 ...>, @on_failure=[]>, @first_header_line=nil, @status_message=nil, @headers={}>
(byebug) typhoeus_response.status_message
nil
(byebug) typhoeus_response.return_message
"Couldn't resolve host name"
(byebug) 

Status_message is nil and the return_message is "Could't resolve host name"
When the status is created it is done as
webmock_response.status = [typhoeus_response.code, typhoeus_response.status_message]

From there on the actual problem for my case is that this gets saved in a vcr cassette as

- request:
    method: post
    uri: http://post_zip.pixel/2
    body:
      encoding: US-ASCII
      string: ''
    headers:
      User-Agent:
      - RetreaverPinger/2.0 (+https://retreaver.com/bot)
      Expect:
      - ''
  response:
    status:
      code: 0
      message:
    headers: {}
    body:
      encoding: ASCII-8BIT
      string: ''
  recorded_at: Fri, 03 May 2024 07:59:00 GMT

where the status code is 0 and the message is empty.

This leads to the following situation. The first time a request is made and there is no cassette typhoeus has return_message as "Could not resolve host" and we can test in our specs that the host was not reached and we've shown the user the error message.

The second time the spec is ran there is already a cassette. The cassette has status message as empty and the test no longer works as it does not load "could not resolve host" into the typhoeus return_message

Probably something along the lines of

        def self.build_webmock_response(typhoeus_response)
          webmock_response = WebMock::Response.new
          status_message = typhoeus_response.status_message
          status_message ||= typhoeus_response.return_message if typhoeus_response.code == 0

          webmock_response.status = [typhoeus_response.code, status_message]

could be useful, but it will mess up status_message with return_message and return message should probably be saved/loaded in another way

@thebravoman thebravoman changed the title Typhoeus return message lost when creating a Webmock response Typhoeus return_message lost when creating a Webmock response May 3, 2024
@bblimke
Copy link
Owner

bblimke commented May 22, 2024

@thebravoman Thank you for reporting this issue.

The return_message information is not based on the response code but on the return_code, which is not part of HTTP but rather an internal aspect of libcurl. For example, status code 0 is also returned on a timeout.

Please consider the following example:

irb(main):002> res = Typhoeus.get("http://post_zip.pixel/2")
=>
#<Typhoeus::Response:0x0000000129bb1410
...
irb(main):003> res.code
=> 0
irb(main):004> res.return_code
=> :couldnt_resolve_host
irb(main):005> res.return_message
=> "Couldn't resolve host name"
irb(main):006> Ethon::Curl.easy_strerror(:couldnt_resolve_host)
=> "Couldn't resolve host name"

WebMock::Response only contains HTTP attributes and doesn't carry any HTTP client-specific data, only pure HTTP response information like status code and status message.

The recorded response in the VCR YAML is correct since the response status message is nil:

irb(main):010> res.status_message
=> nil

We could possibly extend WebMock::Response to carry client_specific_response_attributes that would contain return_code and return_message. However, even then, VCR would not record these attributes as VCR also doesn't support any attributes other than pure HTTP data. Therefore, the solution is not going to work unless both WebMock and VCR support client-specific response attributes.

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

2 participants