HTTParty :: Response преобразуется в Hash при передаче в качестве аргумента другому методу - PullRequest
0 голосов
/ 08 января 2019

У меня есть сервисный метод, который делает запросы API, и если ответ не был в порядке, он уведомил бы Bugsnag. Это выглядит так:

def send_request
  @response = HTTParty.get(api_endpoint, options)
  return JSON.parse(@response.body, symbolize_names: true) if @response.ok?
  raise StandardError.new(JSON.parse(@response.body))
rescue StandardError => exception
  BugsnagService.notify(exception, @response)
end

Мой BugsnagService#notify выглядит примерно так:

class BugsnagService
  def self.notify(exception, response = nil, **options)
    if response
      response_body = if valid_json?(response.body) # Error right here
                        JSON.parse(response.body)
                      else
                        response.body
                      end
      options[:response_body] = response_body
      options[:response_code] = response.code
    end

    # Raising exception in test and development environment, or else the exception will be
    # silently ignored.
    raise exception if Rails.env.test? || Rails.env.development?

    Bugsnag.notify(exception) do |report|
      report.add_tab(:debug_info, options) if options.present?
    end
  end

  def self.valid_json?(json_string)
    JSON.parse(json_string)
    true
  rescue JSON::ParserError => e
    false
  end
end

Я установил response = nil в своем методе notify, потому что не каждая ошибка является ошибкой API, поэтому иногда я просто вызываю BugsnagService.notify(exception).

Я обнаружил, что, если я просто назову это так, как в приведенном выше фрагменте кода, возникнет ошибка, говорящая о том, что он не может вызвать .body на Hash. Каким-то образом, когда я передаю @response в BugsnagService#notify, объект превращается из HTTParty::Response в Hash.

Но если я передам что-то для параметра **options, оно будет работать. Так что я могу назвать это так:

BugsnagService.notify(exception, @response, { })

Я пытался выяснить это, но я не мог найти ничего, что могло бы объяснить это. Я не уверен, что что-то не так с тем, как я определяю свои параметры, или это ошибка с гемом HTTParty. Кто-нибудь может понять, почему это происходит? Спасибо!

1 Ответ

0 голосов
/ 08 января 2019

Проблема в том, что ваш @response передается как options, так как response может быть nil. Двойной восклицательный знак преобразует его в хеш.

Попробуйте:

def testing(x, y = nil, **z)
  puts "x = #{x}"
  puts "y = #{y}"
  puts "z = #{z}"
end

testing 1, 2, z: 3
#=> x = 1
#=> y = 2
#=> z = {:z=>3}

testing 1, y: 2
#=> x = 1
#=> y = 
#=> z = {:y=>2}

testing 1, { y: 2 }, {}
#=> x = 1
#=> {:y=>2}
#=> {}

Я бы предположил, что лучшим подходом было бы иметь response как ключевое слово arg, как в:

def self.notify(exception, response: nil, **options)
  ...
end

Таким образом, вы все равно можете опустить или включить ответ по желанию и передать последующие параметры.

...