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

Please don't implement .nil? #568

Open
patrick-minton opened this issue Jan 25, 2018 · 12 comments
Open

Please don't implement .nil? #568

patrick-minton opened this issue Jan 25, 2018 · 12 comments

Comments

@patrick-minton
Copy link

Ran into this today:

[2] pry(some_code)> response
=> nil
...
[8] pry(some_code)> response == nil
=> false
[9] pry(some_code)> response.nil?
=> true

Had to do this because we were assuming that code like this would cover the nil case:

raise SomeError unless response

Took me a bit of digging to find out that HTTParty::Response implements nil?:

https://github.com/jnunemaker/httparty/blob/master/lib/httparty/response.rb#L58

I don't think this is a good idea. It is widely expected behavior in ruby that nil? isn't overwritten, since nil is a singleton, so these are almost universally treated as equivalent:

some_object == nil
some_object.nil?

This is important because if they're equivalent, you can use "truthiness" to check if the object itself is nil, as opposed to if the response's body is nil, which is a different thing entirely. The definition of nil? above even includes an empty string in the response body, which is, again, not at all the same as when the response itself is nil.

This method really should be .blank? or some such.

@hydrogen18
Copy link
Contributor

This was carried over by mself when I refactored the Response class. I didn't see it as a great idea but was trying not to just yank the rug out from people using this library. I've sat through similar conversations with co-workers as your pry sessions where the code is baffling nil? but also an instance of something other than NilClass

Your points are valid, but we should bump a significant version number( 15->16 here I think) since this is going to break lots of folks code.

@jnunemaker
Copy link
Owner

I think I'm in favor of this. It very likely could break a lot of people's use but feels like the right thing. I believe I added nil? (if it was me) way back in the day when things were a bit more wild west.

@TheSmartnik
Copy link
Collaborator

@jnunemaker In favor as well, but I think we should add a deprecation warning first.
I'll create a pr for this later today

sihugh added a commit to alphagov/search-api that referenced this issue Dec 18, 2019
Resolves:

> [DEPRECATION] HTTParty will no longer override `response#nil?`.
> This functionality will be removed in future versions. Please, add explicit
> check `response.body.nil? || response.body.empty?`. For more info refer
> to: jnunemaker/httparty#568
> /lib/learn_to_rank/ranker.rb:63:in `ranker_error'
bilbof pushed a commit to alphagov/search-api that referenced this issue Dec 19, 2019
This resolves a deprecation warning from the HTTParty gem.

> HTTParty will no longer override `response#nil?`. This functionality will be
> removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`.
> For more info refer to: jnunemaker/httparty#568.
sihugh added a commit to alphagov/search-api that referenced this issue Dec 19, 2019
Resolves:

> [DEPRECATION] HTTParty will no longer override `response#nil?`.
> This functionality will be removed in future versions. Please, add explicit
> check `response.body.nil? || response.body.empty?`. For more info refer
> to: jnunemaker/httparty#568
> /lib/learn_to_rank/ranker.rb:63:in `ranker_error'
sihugh added a commit to alphagov/search-api that referenced this issue Dec 19, 2019
We'll now check separately for response and the response body being nil
or empty as per the deprecated source in https://github.com/jnunemaker/httparty/blob/689e64bb2db0ad454b89519ecd5e2fcfee74c90c/lib/httparty/response.rb#L83

Resolves:

> [DEPRECATION] HTTParty will no longer override `response#nil?`.
> This functionality will be removed in future versions. Please, add explicit
> check `response.body.nil? || response.body.empty?`. For more info refer
> to: jnunemaker/httparty#568
> /lib/learn_to_rank/ranker.rb:63:in `ranker_error'
rastamhadi added a commit to rastamhadi/ruby_weekly_ja that referenced this issue Feb 7, 2020
[DEPRECATION] HTTParty will no longer override `response#nil?`.
This functionality will be removed in future versions.
Please, add explicit check `response.body.nil? || response.body.empty?`.
For more info refer to:
jnunemaker/httparty#568

Solution from:
forem/forem#5297
jmortlock added a commit to sealink/quicktravel_client that referenced this issue Jun 1, 2020
…ide `response#nil?`. This functionality will be removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`. For more info refer to: jnunemaker/httparty#568
jmortlock added a commit to sealink/quicktravel_client that referenced this issue Jun 1, 2020
…ide `response#nil?`. This functionality will be removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`. For more info refer to: jnunemaker/httparty#568
tubbo pushed a commit to tubbo/NeverBounceApi-Ruby that referenced this issue Jul 9, 2020
HTTParty now throws a warning when you try to call `HTTParty::Response#nil?`:

```
[DEPRECATION] HTTParty will no longer override `response#nil?`. This functionality will be removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`. For more info refer to: jnunemaker/httparty#568
```

To resolve this, `require_attr` has been altered to now perform a
`body.nil?` check when the attribute being checked for nil is an
`HTTParty::Response`. This issue was somewhat difficult to reproduce
in your test suite due to the extensive amount of mocking going on, as
well as the fact that `Gemfile.lock` was committed. This warning wasn't
occurring in tests, so I dove in a bit and learned that none of the
tests actually pass a real `HTTParty::Response` into `require_attr`, so
you'd never see this warning in tests but it definitely happens in the
real world. Even if you had been, the fact that `Gemfile.lock` was
committed prevented HTTParty from being updated locally, so the tests
were not actually running against the version of HTTParty that
applications consuming this library have installed.

To resolve this, I deleted `Gemfile.lock` from the repo and added it to
`.gitignore`. This file is not used when you publish to RubyGems.org, as
RubyGems only looks at the `.gemspec` file to figure out dependencies.
This is also the case for consuming applications. It's a general good
practice to not commit `Gemfile.lock` in RubyGem libraries so that
you're always running against the gems that an application would end up
installing as dependencies of your gem.
@jaredlt
Copy link

jaredlt commented Mar 12, 2021

A note for future troubleshooters: In my case it wasn't a call to response.nil? directly but rather I was using Nokogiri:

Old code

response = HTTParty.get('https://www.google.com')
page = Nokogiri::HTML(response) # this used to work

Fix

page = Nokogiri::HTML(response.body) # update to this

timabell added a commit to timabell/tapestry-archive that referenced this issue Jun 8, 2021
magnusvk added a commit to magnusvk/NeverBounceApi-Ruby that referenced this issue Aug 3, 2021
We recently upgraded httparty in our project and now our test output is
littered with deprecation warnings like this:

```
[DEPRECATION] HTTParty will no longer override `response#nil?`. This functionality will be removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`. For more info refer to: jnunemaker/httparty#568
/Users/magnusvk/.gem/ruby/2.7.2/gems/neverbounce-api-1.2.0/lib/never_bounce/api/feature/require_attr.rb:22:in `block in require_attr'
```

It took me some time to figure out what's going on, but the issue is
that `server_ok` in `NeverBounce::API::Session` calls `require_attr` on
the HTTParty response and then `require_attr` calls `.nil?` on that
HTTParty response object.

This actually all seems fine and I don't think the proposed change in
HTTParty will break things here as the intended purpose of
`require_attr` really just seems to be to check that the response is not
`nil`.

This change here is equivalent to the future behavior after HTTParty
makes its change, and it side-steps the deprecation warning.
@viktorradnai
Copy link

Another note for future troubleshooters: logging the response object will trigger the depreciation warning as well:

require "httparty"
require 'logger'

logger = Logger.new($stdout)

response = HTTParty.get('https://www.google.com')
logger.debug(response)

@jaredbeck
Copy link
Contributor

jaredbeck commented Apr 7, 2022

In my experience, when a Net::ReadTimeout occurs, then HTTParty.post will return an actual nil. If I'm correct (it's not documented, just my observation) then this is something everyone should check for. Unfortunately, when they do add such a .nil? check, they will now get a deprecation warning.

.. Please, add explicit check response.body.nil? || response.body.empty?. ..

The warning's advice is dangerously misleading. Following the advice would cause a NoMethodError ("no method body for NilClass"). Perhaps the warning's advice can be corrected?

@pkoch
Copy link

pkoch commented Oct 12, 2022

For anyone looking to suppress these warnings where they can't do anything about them (in my case, in ActiveSupport::Cache), you can install warning and have something like:

Warning.ignore(
    /#{Regexp.quote("HTTParty will no longer override `response#nil?`.")}.+#{Object.const_source_location('ActiveSupport::Cache')[0]}/m,
)

@GeorgeKaraszi
Copy link

I would love to see this warning stripped away. Many things, such as loggers and application debuggers, call .nil? under the hood, so this warning gets spammed quite a lot. Most value aggregators rely on that method too since it's Ruby's most fundamental routine for method guarding and is often aliased/used in other things such as Rail's .blank? method.

I.E. it's a warning pretty much completely unavoidable in a lot of circumstances, even if we're not checking or caring about the response body itself.

For those looking to suppress it:

HTTParty::Response.class_eval do
  def warn_about_nil_deprecation
  end
end

@key88sf
Copy link

key88sf commented May 27, 2023

Just curious when in practice the response object is actually nil? It seems like either there is a response (even if it's an http error), or an exception is raised. I've never actually seen the call return and the response object nil. Can you show an example of when this would happen?

@patrick-minton
Copy link
Author

It's been a minute since I worked at the company that originally used this code, and which caused me to file this, but I can envision a few ways.

For instance, if the response is fetched in a begin / rescue block, and you did something like this:

response = HTTParty.get('http://no.such.url')

In this case that throws a SocketError. If you catch that error in a rescue block, response is now actually nil

I am sure there are other ways it can happen.

@jaredbeck
Copy link
Contributor

jaredbeck commented May 30, 2023

As I mentioned above, a Net::ReadTimeout will also cause post to return an actual nil.

@fmichaut-diff
Copy link

Could we get a .blank? method on HTTParty::Response then ?
This would solve the usecase of reponse being nil (since Rail's blank? method works on nil) as well as response.body being blank and all could be tested with response.blank? which would be the previous behaviour of the overiden nil?

Adding a blank? method before the major version change would allow us to migrate the code now without breaking anything and ensure we have removed every warning so we can be ready when the breaking change comes

tahder added a commit to tahder/puppet-graylog_api that referenced this issue Dec 19, 2024
Get rid off the DEPRECATED warning in related to that functionality..

==> graylog: [DEPRECATION] HTTParty will no longer override `response#nil?`. This functionality will be removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`. For more info refer to: jnunemaker/httparty#568
==> graylog: /tmp/vagrant-puppet/environments/local/local-modules/graylog_api/lib/puppet/provider/graylog_api.rb:109:in `request'
==> graylog: [DEPRECATION] HTTParty will no longer override `response#nil?`. This functionality will be removed in future versions. Please, add explicit check `response.body.nil? || response.body.empty?`. For more info refer to: jnunemaker/httparty#568
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests