algoliasearch-rails icon indicating copy to clipboard operation
algoliasearch-rails copied to clipboard

Algolia::AlgoliaHttpError after upgrade to 2.0.0

Open marckohlbrugge opened this issue 3 years ago • 5 comments

Description

I just upgraded to 2.0.0 of this gem and am now receiving the following exception when doing a search:

Algolia::AlgoliaHttpError: This host is read-only (ie. this is a DSN), write operations are not accepted
from /Users/marc/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/algolia-2.0.4/lib/algolia/transport/transport.rb:72:in `block in request'

Steps To Reproduce

The algolia gem seems to work fine. For comparison:

AlgoliaSearch.configuration = { application_id: "…", api_key: "…" }

class Startup < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch do
    # Setting attributes etc, which all worked before
  end
end

Startup.search('test')
# => Algolia::AlgoliaHttpError: This host is read-only (ie. this is a DSN), write operations are not accepted from /Users/marc/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/algolia-2.0.4/lib/algolia/transport/transport.rb:72:in `block in request'

# Using the same app id and key as before
client = Algolia::Search::Client.create(AlgoliaSearch.configuration[:application_id], AlgoliaSearch.configuration[:api_key])
index = client.init_index('Startup_development')
index.search('test') # => returns results as expected

Credentials

I double checked the credentials and even tried creating new ones with the right privileges. That didn't help. But as you can see in the algolia code example the credentials do indeed seem valid.

Versions

  • Rails version: 6.1.3.1
  • Algolia Rails integration version: algoliasearch-rails (2.0.0)
  • Algolia Client Version: algolia (2.0.4)
  • Language Version: ruby 2.7.2p137

marckohlbrugge avatar May 04 '21 22:05 marckohlbrugge

Okay, so I dug a little bit and it seems like something goes wrong when trying to view or change the settings. So I tried adding all the necessary ACLs to my API key, but that didn't work. Adding check_settings: false did solve the above error, but introduced a new one.

Calling Startup.search("test") returns the follow error:

NoMethodError: undefined method `map' for nil:NilClass
from /Users/marc/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/algoliasearch-rails-2.0.0/lib/algoliasearch-rails.rb:689:in `algolia_search'

It turns out the code is trying to access json['hits'] which does not exist. Although json[:hits] does. That seems like a bug.

marckohlbrugge avatar May 04 '21 23:05 marckohlbrugge

Found this:

https://github.com/algolia/algoliasearch-rails/blob/64b4f9ed338d9f9cc1ab873251a08561c6e03623/spec/integration_spec.rb#L15

Adding symbolize_keys: false to my configuration solved the above issue. I suggest this is added as a default setting, since it seems like the gem requires it. Alternatively the gem can be updated to use the default, symbolised keys.

marckohlbrugge avatar May 04 '21 23:05 marckohlbrugge

Update: I still get the This host is read-only (ie. this is a DSN), write operations are not accepted error message.

I thought setting check_settings: false solved it, but apparently not. Any suggestions on how to further debug this?

marckohlbrugge avatar May 06 '21 11:05 marckohlbrugge

AlgoliaSearch.client.instance_variable_get("@config").default_hosts.first.url
=> "MYAPPID-dsn.algolia.net"

Looks like it's using a DSN host by default. Those are indeed read-only. Any idea why it would use that?

marckohlbrugge avatar May 06 '21 12:05 marckohlbrugge

I think I found a bug in the Ruby client.

# algolia-2.0.4/lib/algolia/http/http_requester.rb
# Line 67
def connection(host)
  @connection ||= Faraday.new(build_url(host)) do |f|
    f.adapter @adapter.to_sym
  end
end

At some point in the code algolia-2.0.4/lib/algolia/transport/transport.rb decides which host to use depending on whether it's for a read or write request. For read requests it uses a read-only DSN host.

That host is then passed to this connection method in algolia-2.0.4/lib/algolia/http/http_requester.rb so it can build a connection.

However, because this method memoizes @connection value there's a chance it will end up a previously created connection. If this previous connection used a read-only host, and the new connection is for a write request, then you'll get the error I experienced.

Since this seems like a bug with the ruby client, I will cross-post an issue there.

marckohlbrugge avatar May 06 '21 12:05 marckohlbrugge