Skip to content

Conversation

@osyoyu
Copy link
Contributor

@osyoyu osyoyu commented Dec 4, 2025

The try-open_timeout-then-fallback-to-timeout introduced in 1903ced (#224) works well, but when it errors due to any reason in Rubies which do not support open_timeout, it spits the rescued ArgumentError that is unrelated to user code and not actionable.

Net::HTTP.start('foo.bar', 80)

/.../net-http-0.8.0/lib/net/http.rb:1691:in 'TCPSocket#initialize': Failed to open TCP connection to foo.bar:80 (getaddrinfo(3): nodename nor servname provided, or not known) (Socket::ResolutionError)
        from /.../net-http-0.8.0/lib/net/http.rb:1691:in 'IO.open'
        from /.../net-http-0.8.0/lib/net/http.rb:1691:in 'block in Net::HTTP#connect'
        from /.../timeout-0.4.4/lib/timeout.rb:188:in 'block in Timeout.timeout'
        from /.../timeout-0.4.4/lib/timeout.rb:195:in 'Timeout.timeout'
        from /.../net-http-0.8.0/lib/net/http.rb:1690:in 'Net::HTTP#connect'
        from /.../net-http-0.8.0/lib/net/http.rb:1655:in 'Net::HTTP#do_start'
        from /.../net-http-0.8.0/lib/net/http.rb:1635:in 'Net::HTTP#start'
        from /.../net-http-0.8.0/lib/net/http.rb:1064:in 'Net::HTTP.start'
        (snip)
/.../net-http-0.8.0/lib/net/http.rb:1682:in 'TCPSocket#initialize': unknown keyword: :open_timeout (ArgumentError)

          sock = TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        from /.../net-http-0.8.0/lib/net/http.rb:1682:in 'IO.open'
        from /.../net-http-0.8.0/lib/net/http.rb:1682:in 'Net::HTTP#connect'
        from /.../net-http-0.8.0/lib/net/http.rb:1655:in 'Net::HTTP#do_start'
        from /.../net-http-0.8.0/lib/net/http.rb:1635:in 'Net::HTTP#start'
        from /.../net-http-0.8.0/lib/net/http.rb:1064:in 'Net::HTTP.start'
        (snip)
        ... 8 levels...

This patch suppresses the ArgumentError by moving the retry out of the rescue clause.

The try-open_timeout-then-fallback-to-timeout introduced in
1903ced works well, but when it errors
due to any reason in Rubies which do not support `open_timeout`, it
spits the rescued ArgumentError that is unrelated to user code and not
actionable.

    Net::HTTP.start('foo.bar', 80)

    /.../net-http-0.8.0/lib/net/http.rb:1691:in 'TCPSocket#initialize': Failed to open TCP connection to foo.bar:80 (getaddrinfo(3): nodename nor servname provided, or not known) (Socket::ResolutionError)
            from /.../net-http-0.8.0/lib/net/http.rb:1691:in 'IO.open'
            from /.../net-http-0.8.0/lib/net/http.rb:1691:in 'block in Net::HTTP#connect'
            from /.../timeout-0.4.4/lib/timeout.rb:188:in 'block in Timeout.timeout'
            from /.../timeout-0.4.4/lib/timeout.rb:195:in 'Timeout.timeout'
            from /.../net-http-0.8.0/lib/net/http.rb:1690:in 'Net::HTTP#connect'
            from /.../net-http-0.8.0/lib/net/http.rb:1655:in 'Net::HTTP#do_start'
            from /.../net-http-0.8.0/lib/net/http.rb:1635:in 'Net::HTTP#start'
            from /.../net-http-0.8.0/lib/net/http.rb:1064:in 'Net::HTTP.start'
            (snip)
    /.../net-http-0.8.0/lib/net/http.rb:1682:in 'TCPSocket#initialize': unknown keyword: :open_timeout (ArgumentError)

              sock = TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            from /.../net-http-0.8.0/lib/net/http.rb:1682:in 'IO.open'
            from /.../net-http-0.8.0/lib/net/http.rb:1682:in 'Net::HTTP#connect'
            from /.../net-http-0.8.0/lib/net/http.rb:1655:in 'Net::HTTP#do_start'
            from /.../net-http-0.8.0/lib/net/http.rb:1635:in 'Net::HTTP#start'
            from /.../net-http-0.8.0/lib/net/http.rb:1064:in 'Net::HTTP.start'
            (snip)
            ... 8 levels...

This patch suppresses the ArgumentError by moving the retry out of the
rescue clause.
Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, that's even simpler, no recursive call just moving the Timeout.timeout outside the rescue and using an early return

@eregon eregon merged commit 0f6986d into ruby:master Dec 5, 2025
22 checks passed
@osyoyu
Copy link
Contributor Author

osyoyu commented Dec 5, 2025

Thank you!

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

Successfully merging this pull request may close these issues.

2 participants