Skip to content

Allow ConnectionRefusedError to be captured as Errno::ECONNREFUSED #368

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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Contributors.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ Contributions since:
* Cody Cutrer (ccutrer)
* WoodsBagotAndreMarquesLee
* Rufus Post (mynameisrufus)
* Akamai Technologies, Inc. (jwedoff)
2 changes: 1 addition & 1 deletion lib/net/ldap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1320,7 +1320,7 @@ def new_connection
# Force connect to see if there's a connection error
connection.socket
connection
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, Net::LDAP::ConnectionRefusedError => e
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
@result = {
:resultCode => 52,
:errorMessage => ResultStrings[ResultCodeUnavailable],
Expand Down
97 changes: 54 additions & 43 deletions lib/net/ldap/error.rb
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
class Net::LDAP
class LdapError < StandardError
def message
"Deprecation warning: Net::LDAP::LdapError is no longer used. Use Net::LDAP::Error or rescue one of it's subclasses. \n" + super
end
# define Error as a module so that we can use it in exceptions derived from
# other classes (e.g. Errno::ECONNREFUSED)
module Error; end
# define a base class for our "normal" errors
class ErrorClass < StandardError;
include Error
end
class AlreadyOpenedError < ErrorClass; end
class SocketError < ErrorClass; end

class Error < StandardError; end
# make ConnectionRefusedError a kind of Errno::ECONNREFUSED
# so that code looking for that exception will work correctly
class ConnectionRefusedError < Errno::ECONNREFUSED
include Error

class AlreadyOpenedError < Error; end
class SocketError < Error; end
class ConnectionRefusedError < Error;
def initialize(*args)
warn_deprecation_message
super
end
# don't print a deprication message on initialization or printing the message.
# we control those, and code that is using the proper calls will still get the
# warnings pointlessly.

def message
# display the deprication warning on === which will get called any time an exception
# goes through a handler like
# begin
# ...
# rescue ConnectionRefusedError => e
# <handler code>
# end
#
# which *is* the code we want people to stop using
def self.===(val)
warn_deprecation_message
super
end

private

def warn_deprecation_message
def self.warn_deprecation_message
warn "Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead."
end
end
class ConnectionError < Error

class ConnectionError < ErrorClass
def self.new(errors)
error = errors.first.first
if errors.size == 1
if error.kind_of? Errno::ECONNREFUSED
return Net::LDAP::ConnectionRefusedError.new(error.message)
end

return Net::LDAP::Error.new(error.message)
return Net::LDAP::ErrorClass.new(error.message)
end

super
Expand All @@ -45,29 +56,29 @@ def initialize(errors)
super(message)
end
end
class NoOpenSSLError < Error; end
class NoStartTLSResultError < Error; end
class NoSearchBaseError < Error; end
class StartTLSError < Error; end
class EncryptionUnsupportedError < Error; end
class EncMethodUnsupportedError < Error; end
class AuthMethodUnsupportedError < Error; end
class BindingInformationInvalidError < Error; end
class NoBindResultError < Error; end
class SASLChallengeOverflowError < Error; end
class SearchSizeInvalidError < Error; end
class SearchScopeInvalidError < Error; end
class ResponseTypeInvalidError < Error; end
class ResponseMissingOrInvalidError < Error; end
class EmptyDNError < Error; end
class HashTypeUnsupportedError < Error; end
class OperatorError < Error; end
class SubstringFilterError < Error; end
class SearchFilterError < Error; end
class BERInvalidError < Error; end
class SearchFilterTypeUnknownError < Error; end
class BadAttributeError < Error; end
class FilterTypeUnknownError < Error; end
class FilterSyntaxInvalidError < Error; end
class EntryOverflowError < Error; end
class NoOpenSSLError < ErrorClass; end
class NoStartTLSResultError < ErrorClass; end
class NoSearchBaseError < ErrorClass; end
class StartTLSError < ErrorClass; end
class EncryptionUnsupportedError < ErrorClass; end
class EncMethodUnsupportedError < ErrorClass; end
class AuthMethodUnsupportedError < ErrorClass; end
class BindingInformationInvalidError < ErrorClass; end
class NoBindResultError < ErrorClass; end
class SASLChallengeOverflowError < ErrorClass; end
class SearchSizeInvalidError < ErrorClass; end
class SearchScopeInvalidError < ErrorClass; end
class ResponseTypeInvalidError < ErrorClass; end
class ResponseMissingOrInvalidError < ErrorClass; end
class EmptyDNError < ErrorClass; end
class HashTypeUnsupportedError < ErrorClass; end
class OperatorError < ErrorClass; end
class SubstringFilterError < ErrorClass; end
class SearchFilterError < ErrorClass; end
class BERInvalidError < ErrorClass; end
class SearchFilterTypeUnknownError < ErrorClass; end
class BadAttributeError < ErrorClass; end
class FilterTypeUnknownError < ErrorClass; end
class FilterSyntaxInvalidError < ErrorClass; end
class EntryOverflowError < ErrorClass; end
end
8 changes: 4 additions & 4 deletions test/integration/test_bind.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_bind_tls_with_bad_hostname_verify_peer_ca_fails
ca_file: CA_FILE },
)
error = assert_raise Net::LDAP::Error,
Net::LDAP::ConnectionRefusedError do
Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
Expand All @@ -90,7 +90,7 @@ def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails
tls_options: TLS_OPTS.merge(ca_file: CA_FILE),
)
error = assert_raise Net::LDAP::Error,
Net::LDAP::ConnectionRefusedError do
Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
Expand All @@ -106,7 +106,7 @@ def test_bind_tls_with_bad_hostname_ca_no_opt_merge_fails
tls_options: { ca_file: CA_FILE },
)
error = assert_raise Net::LDAP::Error,
Net::LDAP::ConnectionRefusedError do
Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
Expand Down Expand Up @@ -141,7 +141,7 @@ def test_bind_tls_with_bogus_hostname_system_ca_fails
@ldap.host = '127.0.0.1'
@ldap.encryption(method: :start_tls, tls_options: {})
error = assert_raise Net::LDAP::Error,
Net::LDAP::ConnectionRefusedError do
Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
Expand Down
35 changes: 33 additions & 2 deletions test/test_ldap_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def test_result_for_connection_failed_is_set

ldap_client = Net::LDAP.new(host: '127.0.0.1', port: 12345)

assert_raise Net::LDAP::ConnectionRefusedError do
assert_raise_kind_of Errno::ECONNREFUSED do
ldap_client.bind(method: :simple, username: 'asdf', password: 'asdf')
end

Expand All @@ -86,11 +86,42 @@ def test_blocked_port
def test_connection_refused
connection = Net::LDAP::Connection.new(:host => "fail.Errno::ECONNREFUSED", :port => 636, :socket_class => FakeTCPSocket)
stderr = capture_stderr do
assert_raise Net::LDAP::ConnectionRefusedError do
assert_raise_kind_of Errno::ECONNREFUSED do
connection.socket
end
end
end

# explicity test deprication warning; it shows when Net::LDAP::ConnectionRefusedError is used a rescue match
# assert_raise/assert_raise_kind_of doesn't trigger it
def test_deprication_warning_on_exception
connection = Net::LDAP::Connection.new(:host => "fail.Errno::ECONNREFUSED", :port => 636, :socket_class => FakeTCPSocket)
got_exception = false
stderr = capture_stderr do
begin
connection.socket
rescue Net::LDAP::ConnectionRefusedError
got_exception = true
end
end
assert_equal("Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead.\n", stderr)
assert got_exception, "Didn't raise exception"
end

def test_deprication_warning_on_other_exception
connection = Net::LDAP::Connection.new(:host => "fail.StandardError", :port => 636, :socket_class => FakeTCPSocket)
got_exception = false
stderr = capture_stderr do
assert_raise StandardError do
begin
connection.socket
rescue Net::LDAP::ConnectionRefusedError
got_exception = true
end
end
end
assert_equal("Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead.\n", stderr)
assert !got_exception, "Net::LDAP::ConnectionRefusedError should not have matched"
end

def test_connection_timeout
Expand Down