rescue aws s3 exception in rails. - ruby-on-rails

I am trying to rescue an aws s3 exception.
class FileManager
def fetchFile
begin
s3.get_object(bucket:'myBucket', key: file_name)
rescue Aws::S3::Errors => e
debugger
end
end
end
Then when I call the method from console
FileManager.fetch_file('Non existing file')
I am not getting the debugger instead there is an error message in the console
Aws::S3::Errors::NoSuchKey: The specified key does not exist.

I believe this has what your looking for (assuming you are using this gem):
https://github.com/marcel/aws-s3#when-things-go-wrong

You can rescue all S3 errors using ServiceError
begin
# ...
rescue Aws::S3::Errors::ServiceError => e
# ...
end

Related

How to catch raised exception in rake task

I have a rake task that loops through rows in CSV file, and inside that loop, there's a begin/rescue block to catch any possible raised exception. But when I run it, it keeps on saying 'rake aborted!' and it is not entering the rescue block
CSV.foreach(path, :headers => true) do |row|
id = row.to_hash['id'].to_i
if id.present?
begin
# call to mymethod
rescue => ex
puts "#{ex} error executing task"
end
end
end
...
def mymethod(...)
...
begin
response = RestClient.post(...)
rescue => ex
raise Exception.new('...')
end
end
Expected: It should finish looping all the rows of the CSV
Actual result: It stops after reaching the 'raise' exception saying that:
rake aborted!
Exception: error message here
...
Caused by:
RestClient::InternalServerError: 500 Internal Server Error
You can use next to skip the faulty step of loop:
CSV.foreach(path, :headers => true) do |row|
id = row.to_hash['id'].to_i
if id.present?
begin
method_which_doing_the_staff
rescue SomethingException
next
end
end
end
And raise the exception inside your method:
def method_which_doing_the_staff
stuff
...
raise SomethingException.new('hasd')
end
I solved this issue by just commenting out the line that is raising an exception because it seems like it the quickest fix for now.
# raise Exception.new('...')
I'm still open to other suggestions if there are any better ways to do it.

Why am I getting sporadic disconnects when using capybara-webkit gem in Rails 4?

I use the capybara-webkit gem to scrape data from certain pages in my Rails application. I've noticed, what seems to be "random" / "sporadic", that the application will crash with the following error:
Capybara::Webkit::ConnectionError: /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/bin/webkit_server failed to start.
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit/server.rb:56:in `parse_port'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit/server.rb:42:in `discover_port'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit/server.rb:26:in `start'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit/connection.rb:67:in `start_server'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit/connection.rb:17:in `initialize'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit/driver.rb:16:in `new'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit/driver.rb:16:in `initialize'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit.rb:15:in `new'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-webkit-1.11.1/lib/capybara/webkit.rb:15:in `block in <top (required)>'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-2.7.1/lib/capybara/session.rb:85:in `driver'
from /home/daveomcd/.rvm/gems/ruby-2.3.1/gems/capybara-2.7.1/lib/capybara/session.rb:233:in `visit'
It happens even after it's already connected and accessed a website multiple times before. Here's a code snippet of what I'm using currently...
if site.url.present?
begin
# Visit the URL
session = Capybara::Session.new(:webkit)
session.visit(site.url) # here is where the error occurs...
document = Nokogiri::HTML.parse(session.body)
# Load configuration options for Development Group
roster_table_selector = site.development_group.table_selector
header_row_selector = site.development_group.table_header_selector
row_selector = site.development_group.table_row_selector
row_offset = site.development_group.table_row_selector_offset
header_format_type = site.config_header_format_type
# Get the Table and Header Row for processing
roster_table = document.css(roster_table_selector)
header_row = roster_table.css(header_row_selector)
header_hash = retrieve_headers(header_row, header_format_type)
my_object = process_rows(roster_table, header_hash, site, row_selector, row_offset)
rescue ::Capybara::Webkit::ConnectionError => e
raise e
rescue OpenURI::HTTPError => e
if e.message == '404 Not Found'
raise "404 Page not found..."
else
raise e
end
end
end
I've even thought perhaps I don't find out why it's happening necessarily - but just recover when it does. So I was going to do a "retry" in the rescue block for the error but it appears the server is just down - so I get the same result when retrying. Perhaps someone knows of a way I can check if the server is down and restart it then perform a retry? Thanks for the help!
So after further investigating it appears that I was generating a new Capybara::Session for each iteration of my loop. I moved it outside of the loop and also added Capybara.reset_sessions! at the end of my loop. Not sure if that helps with anything -- but the issue seems to have been resolved. I'll monitor it for the next hour or so. Below is an example of my ActiveJob code now...
class ScrapeJob < ActiveJob::Base
queue_as :default
include Capybara::DSL
def perform(*args)
session = Capybara::Session.new(:webkit)
Site.where(config_enabled: 1).order(:code).each do |site|
process_roster(site, session)
Capybara.reset_sessions!
end
end
def process_roster(site, session)
if site.roster_url.present?
begin
# Visit the Roster URL
session.visit(site.roster_url)
document = Nokogiri::HTML.parse(session.body)
# processing code...
# pass the session that was created as the final parameter..
my_object = process_rows( ..., session)
rescue ::Capybara::Webkit::ConnectionError => e
raise e
rescue OpenURI::HTTPError => e
if e.message == '404 Not Found'
raise "404 Page not found..."
else
raise e
end
end
end
end
end

Ruby on Rails Error Handling, Catching Error and Message

I'm trying to figure out the best way to catch a specific error thrown AND the error's message in Ruby on Rails. My use case is that I encounter a timeout error every now and then which is thrown with a general error and I want to treat the timeout error differently than other errors within the same general error. I'm not sure what other type of errors could be thrown in the general error but I assume more of them exist. I have some sample code below of how I'm currently handling it, but I was thinking there might be a better way which I haven't found yet?
tries = 0
begin
tries += 1
<code>
rescue Foo::Bar => e
case e.to_s
when 'More specific timeout error message'
retry unless tries >= 5
else
# Let me see other error messages
log.info("Error: #{e.to_s}")
end
end
You can use multi rescue, to handle different errors.
begin
# DO SOMETHING
rescue Net::Timeout => e # change it to the error your want to catch, check the log.
# handle it
rescue SyntaxError => e # just an example
# handle it
rescue => e # any error that not catch by above rescue go here.
# handle it
end
Read more:
http://phrogz.net/programmingruby/tut_exceptions.html
You can try Rollbar, it help report error on production.
Take a look at retriable gem. It seems like a good fit for what you're proposing. Usually you'd rescue from an specific error type, but retriable also gives you the choice to rescue based on the error message.
begin
Retriable.retriable on: { Foo::Bar => /More specific timeout error message/ }, tries: 3 do
# will retry if an error of type Foo::Bar is raised
# and its message matches /More specific timeout error message/
# code here...
end
rescue => e # rescue for everything else
puts e.message # same as e.to_s
end

Rails.logger usage from initializer in development

In my Rails 5 application I am trying to access and use the logger in an initializer:
begin
raise "REDIS_URL environment var not found" unless ENV["REDIS_URL"]
$redis = Redis.new
$redis.ping
Rails.logger.info "Successfully connected to redis: #{ENV["REDIS_URL"]}" if $redis.connected?
rescue Exception => e
Rails.logger.warn e.message
Rails.logger.warn 'API only mode. Request to root will not return any index.html'
end
debugging inside the block I can access it:
(byebug) Rails.logger
#<ActiveSupport::Logger:0x007ffb69ef48d8>
(byebug) Rails.logger.level
0
(byebug)
but I don't see any msg in development. Is the logger supposed to be accessible but not to be used in there? Is this this considered a correct solution?
(It works in production)
thank you

Show template code near error in ERB

If ERB.new(...).result raises an exception how do I get the code and backtrace near it?
Like rails does with it's templates.
I tried what #Nathan suggested before:
begin
ERB.new('<%= fail %>').result
rescue Exception => e
p e
end
=> RuntimeError
That doesn't tell me the position of the error
Try:
begin
ERB.new(...).result
rescue Exception => e
# puts e
# or
# binding.pry if you use the pry gem
end

Resources