docbrown/app/services/twitter_client/client.rb
Kirk Haines ed74f2f245
Abstract DatadogStatsClient to ForemStatsClient (#12304)
* This change abstracts the DatadogStatsClient into a ForemStatsClient.
The purpose of this abstraction is to set the foundation for a subsequent PR that will allow one to use New Relic for recording Forem stats, instead of Datadog, if there is a New Relic configuration found.
This specific change creates an abstraction layer that can be built upon, without changing any actual default behavior. All specs still pass.

* Use delegate instead of explicit methods.

* Delegate instead of explicit methods.

* Fix the error.

* Refactor according to the suggestions in the comments.

* Ooops.  Stats work better when all of the code is committed.

* Removing the alias of count to increment since that was done in error.
2021-01-27 11:25:44 -05:00

72 lines
2.3 KiB
Ruby

module TwitterClient
# Twitter client (users twitter gem as a backend)
class Client
class << self
# adapted from https://api.rubyonrails.org/classes/Module.html#method-i-delegate_missing_to
def method_missing(method, *args, &block)
return super unless target.respond_to?(method, false)
request do
target.public_send(method, *args, &block)
end
end
# adapted from https://api.rubyonrails.org/classes/Module.html#method-i-delegate_missing_to
def respond_to_missing?(method, _include_all = false)
target.respond_to?(method, false) || super
end
private
def request
Honeycomb.add_field("name", "twitter.client")
yield
rescue Twitter::Error => e
record_error(e)
handle_error(e)
end
def record_error(exception)
class_name = exception.class.name.demodulize
Honeycomb.add_field("twitter.result", "error")
Honeycomb.add_field("twitter.error", class_name)
ForemStatsClient.increment(
"twitter.errors",
tags: ["error:#{class_name}", "message:#{exception.message}"],
)
end
def handle_error(exception)
class_name = exception.class.name.demodulize
# raise specific error if known, generic one if unknown
error_class = "::TwitterClient::Errors::#{class_name}".safe_constantize
raise error_class, exception.message if error_class
error_class = if exception.class < Twitter::Error::ClientError
TwitterClient::Errors::ClientError
elsif exception.class < Twitter::Error::ServerError
TwitterClient::Errors::ServerError
else
TwitterClient::Errors::Error
end
raise error_class, exception.message
end
def target
Twitter::REST::Client.new(
consumer_key: SiteConfig.twitter_key.presence || ApplicationConfig["TWITTER_KEY"],
consumer_secret: SiteConfig.twitter_secret.presence || ApplicationConfig["TWITTER_SECRET"],
user_agent: "TwitterRubyGem/#{Twitter::Version} (#{URL.url})",
timeouts: {
connect: 5,
read: 5,
write: 5
},
)
end
end
end
end