Handling connection refused from curb(-fu) call - ruby-on-rails

How can I deal with
Curl::Easy.http_get("dev-server.example.com")
Curl::Err::ConnectionFailedError: Curl::Err::ConnectionFailedError
from a curb or curb-fu call? Our dev servers are up and down so I need to be able to handle this better than getting an exception, the documentation seems very light.

I came across rescue which gave me what I needed
Curl::Easy.http_get("dev-server.example.com") rescue <some action>

Related

How can I stop Rails execution from initializer?

I want to stop the app start up from an initializer.
Something like if a config isn't present, stop server/console, etc.
Also send a message in order to explain the error.
Is there a way to do that?
I looked into initialization events but I cannot make it happen.
Thanks in advance.
Yeah, just raise an exception like you normally would:
raise StandardError, "Stopping app start up because something is missing"
If you're doing this because some config is missing, consider using something like Figaro which does this for you.
Figaro.require_keys("pusher_app_id", "pusher_key", "pusher_secret")
https://github.com/laserlemon/figaro
You can use the Kernel#abort method to do it. It'll stop the application with your provided message and won't throw up any error.
Example:
abort('You need to pass more info to start the application') if some_check_fails?

Sidekiq - Only handle error after x retries?

I'm using sidekiq to process thousands of jobs per hour - all of which ping an external API (Google). One out of X thousand requests will return an unexpected (or empty) result. As far as I can tell, this is unavoidable when dealing with an external API.
Currently, when I encounter such response, I raise an Exception so that the retry logic will automatically take care of it on the next try. Something is only really wrong with the same job fails over and over many times. Exceptions are handled by Airbrake.
However my airbrake gets clogged up with these mini-outages that aren't really 'issues'. I'd like Airbrake to only be notified of these issues if the same job has failed X times already.
Is it possible to either
disable the automated airbrake integration so that I can use the sidekiq_retries_exhausted to report the error manually via Airbrake.notify
Rescue the error somehow so it doesn't notify Airbrake but keep retrying it?
Do this in a different way that I'm not thinking of?
Here's my code outline
class GoogleApiWorker
include Sidekiq::Worker
sidekiq_options queue: :critical, backtrace: 5
def perform
# Do stuff interacting with the google API
rescue Exception => e
if is_a_mini_google_outage? e
# How do i make it so this harmless error DOES NOT get reported to Airbrake but still gets retried?
raise e
end
end
def is_a_mini_google_outage? e
# check to see if this is a harmless outage
end
end
As far as I know Sidekiq has a class for retries and jobs, you can get your current job through arguments (comparing - cannot he effective) or jid (in this case you'd need to record the jid somewhere), check the number of retries and then notify or not Airbrake.
https://github.com/mperham/sidekiq/wiki/API
https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/api.rb
(I just don't give more info because I'm not able to)
if you look for Sidekiq solution https://blog.eq8.eu/til/retry-active-job-sidekiq-when-exception.html
if you are more interested in configuring Airbrake so you don't get these errors untill certain retry check Airbrake::Sidekiq::RetryableJobsFilter
https://github.com/airbrake/airbrake#airbrakesidekiqretryablejobsfilter

How to properly handle errors for "PG::ConnectionBad could not connect to server"?

My app is just a typical Rails with a Postgresql (actually, Postgres app on OS X). I would like to add exception handling when my Rails app cannot connect to the database and show plain text of connection error for now, instead of a Rails error page (or may be static HTML error page later on).
I've tried adding exception below to the application_controller.rb.
# from app/controllers/application_controllers.rb
-------------------------------------------------
rescue_from PG::ConnectionBad, with: :database_connection_error
def :database_connection_error
render plain: "Could not connect to the Database"
end
(code ommited)
but it's not rendering plain text. (I also use this exception snippet on the other controllers. It's working but it's handling a different exception, e.g. I use it to handling ActiveRecord::RecordNotFound error)
Is there any way to handle a PG::ConnectionBad or point out what I am doing wrong here?
Thanks in advance.

Customize exception_notifier, Ruby on Rails

I have successfully added the exception_notifier to my rails app, and it is emailing a notification for all exceptions at the application level (which is exactly what I want). The only problem is that I need to have a few short lines of code ran whenever an exception is raised as well, and am certain that there is a way to add these lines of code onto the notifier. But despite reading the documentation found here: https://github.com/smartinez87/exception_notification I am still unclear what/where I should put things. Can someone please explain this a bit better for me. I am relatively new to ROR. I just need to add some additional code to run whenever the notifier is alerted to an exception.
This seems to be the correct link to the background notification:
Using a begin rescue should do the trick.
def method
sentence1
begin
sentence2
sentence3
rescue => e
ExceptionNotifier.notify_exception(e)
Sentence code1
return action
end
end
As explained here:
https://github.com/smartinez87/exception_notification#background-notifications
So as a shorthand: To do code before or after the notification is sended, but outside of the notification method you need to catch the exception in the method who raised it and work there.
But remember: Catching exceptions should be an exception. If you know what could go wrong, try to fix it, not to catch it.

Releasing a connection in Rails

I'm using Rails 2.3.8.
What's the best way to release a connection on a model to another database?
Let's say I have ModelB.establish_connection("server_b")
Would ModelB.remove_connection do the trick? How would I verify that I've successfully removed the connection?
Looks as though remove_connection is what you're looking for. To verify that you've successfully removed the connection, you could wrap a find method within a rescue block like:
begin
ModelB.find(1)
rescue ConnectionNotEstablished
# if we're here, then we have no connection, which is good in this case
else
# if we're here, then we still have a connection, which is bad...
end

Resources