Hi I have a service class which is pulling information from Hubspot.
module HubspotApi
class CompanyImporter < ApplicationService
MAX_RETRIES = 3
def initialize(company_vid)
@company_vid = company_vid
@attempt = 0
end
def service_body
imported_profile
end
private
attr_reader :company_vid, :attempt
def imported_profile
## load hubspot record over here and take other actions
end
def hubspot_record
@hubspot_record ||= Hubspot::Company.find_by_id(company_vid.to_i)
rescue Hubspot::RequestError
if (attempt += 1) <= MAX_RETRIES
sleep 2**attempt
retry
else
@messages << 'Raise some hubspot error'
end
end
end
end
I tried calling this with an incorrect company_vid
to make sure the retry works properly and I keep getting the error:
NoMethodError: undefined method `+' for nil:NilClass from `rescue in hubspot_record'
Caused by Hubspot::RequestError: Response body: {"status":"error","message":"resource not found"}
I am not sure if I am having a brain-fart here but I just cannot figure out the error here since the variable should be defined
In Ruby, local variables are defined from the moment that an assignment to them is parsed (NOT executed).
Since you are assigning to attempt
, Ruby will make attempt
a local variable of hubspot_record
. However, since it is not initialized, it will evaluate to nil
.
attempt += 1
is equivalent to
attempt = attempt + 1
And since attempt
is un-initialized and evaluates to nil
, this is essentially evaluating nil + 1
.
If you want to use the attribute reader method, you have to make it clear to Ruby that you are intending a message send and not access a local variable. There are two ways to do this: a local variable cannot have a receiver and a local variable cannot have an argument list. So, if you add either one of those, Ruby will know it is a message send and not a local variable:
attempt()
self.attempt
Either one of those will make it clear to Ruby that you intend to call the HubspotApi::CompanyImporter#attempt
method.
However, that still will not work, because you are trying to assign to and you don't actually have an attribute writer, so your next error message is going to be something like
NoMethodError: undefined method `attempt=' for HubspotApi::CompanyImporter
The way to fix this problem pre-Ruby 2.7 is to:
change attr_reader:attempt
to attr_accessor:attempt
And
def hubspot_record
@hubspot_record ||= Hubspot::Company.find_by_id(company_vid.to_i)
rescue Hubspot::RequestError
if (self.attempt = attempt + 1) <= MAX_RETRIES ## This was fixed in Ruby 2.7 but for earlier versions you need to read using self and write directly.
sleep 2**attempt
retry
else
@messages << 'Raise some hubspot error'
end
end
Link for update in Ruby 2.7: https://blog.saeloun.com/2019/12/24/ruby-2-7-allows-calling-a-private-method-with-self.html
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.