Begin Rescue not catching error - ruby-on-rails

I'm using some ruby code wrapped in a begin - rescue block but somehow it manages to still crash.
the block of code looks like this:
# Retrieve messages from server
def get_messages
#connection.select('INBOX')
#connection.uid_search(['ALL']).each do |uid|
msg = #connection.uid_fetch(uid,'RFC822').first.attr['RFC822']
begin
process_message(msg)
add_to_processed_folder(uid) if #processed_folder
rescue
handle_bogus_message(msg)
end
# Mark message as deleted
#connection.uid_store(uid, "+FLAGS", [:Seen, :Deleted])
end
end
Given this code i would assume that if process_message or add_to_processed_folder could not execute then rescue would kick in and call handle_bogus_message. That being said I'm running this code in a production environment and sometimes when i "get" an email message (this is run from a rake task) it dies with a SyntaxError.
For a look at the error message check out http://pastie.org/1028479 and not that process_message that it is referring to is the same process_message above. Is there any reason why begin - rescue won't catch this exception?

rescue without a parameter just rescues exceptions that inherit from StandardError. To rescue a SyntaxError use rescue SyntaxError.
To rescue all exceptions you would use rescue Exception, but note that that's a bad idea (which is why it's not the default behavior of rescue) as explained here and here. Especially this part:
Rescuing Interrupt prevents the user from using CTRLC to exit the program.
Rescuing SignalException prevents the program from responding correctly to signals. It will be unkillable except by kill -9.

rescue without any parameter accepts exceptions raised by StandardError class. Your error type is SyntaxError which is inherited from a different class called ScriptError. All these error classes are subclasses of Exception class. So as sepp2k suggested use rescue Exception to catch all kinds of exceptions.

Related

How to prevent logging Rails stack trace

I'm trying to reduce the amount of noise in my logs and would like to disable Rails from logging the stack trace during errors.
Since I am using an error reporting service (Honeybadger.io) I don't need to see the stack trace in the logs as it's already available in the exception report from the error handling service.
The default Rails middleware DebugExceptions is what logs the errors.
You can remove it with config.middleware.delete(ActionDispatch::DebugExceptions) in your config/environment.rb or config/environments/production.rb
According to the docs you should be able to add a backtrace silencer that excludes every line by returning true in the block.
But, at least with Rails 4.2.5.2, this doesn't appear to be working and even if it did work you would still end up with a line in log about the exception.
Accidentally I discovered that if you raise an error inside a silencer block that this will suppress the error message and the entire backtrace which turns out to be exactly what I'm looking for.
Rails.backtrace_cleaner.add_silencer { |_line| raise }
Combining this hack with the concise_logging gem I can now have logs that look like the following:
Well, Rails.backtrace_cleaner.add_silencer works, but I woulnd call its behaviour predictable
https://github.com/vipulnsward/rails/blob/ecc8f283cfc1b002b5141c527a827e74b770f2f0/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L155-L156
Since application_trace is empty(This is because error is not from user code but route error), we are falling back to framework_trace, which does not filter it (it filters only noise).
You can solve it with creating your own log_formatter. In your development.rb and/or test.rb add
config.log_formatter = SilentLogger.new
config.log_formatter.add_silencer { |line| line =~ /lib/ }
And create simple class in models with only method call required. There you can modify your backtrace as you wish.
class SilentLogger
def initialize
#silencers = []
end
def add_silencer(&block)
#silencers << block
end
def call(severity, timestamp, progname, msg)
backtrace = (String === msg) ? "#{msg}\n" : "#{msg.inspect}\n"
return backtrace if #silencers.empty?
#silencers.each do |s|
backtrace = backtrace.split("\n").delete_if { |line| s.call(line) }
end
backtrace.join("\n")
end
end

How do I handle errors when using api_auth gem?

Currently for a project I am using api_auth gem. I am hitting on an external api in a function by making a signed request. Currently my code looks like this.
access_id = "someKey"
secret_key = "someRandomGeneratedKey"
request = RestClient::Request.new(url: 'serverUrl', method: get, headers:'headers')
#signed_request = ApiAuth.sign!(access_id, secret_key, request)
#signed_request.execute
I am unable to apply any error handling code to that last statement where I execute the request. Any suggestions?
You have to use begin rescue block to exception handling.
begin
#TODO Exception occurring statement
rescue
#Exception handling code
end
As you should only rescue specific exception, rather than all.
So as your code suggest that you are using rest_client & api-auth gem so from documentation you can get list of exception that this gem raise.
Example - For rest_client below exceptions need to be handled. (probably this is the solution of your problem, just replace last line as given below)
begin
#signed_request.execute
rescue RestClient::ExceptionWithResponse, URI::InvalidURIError, RestClient::InternalServerError => err
p err
end
There are few Exceptions also generated by api-auth gem also like
ApiAuth::ApiAuthError, ApiAuth::UnknownHTTPRequest so you need to rescue all this exceptions.
Reference link -
http://www.rubydoc.info/gems/api-auth/1.4.0/
Thanks!

Error in an after hook, PG::InFailedSqlTransaction from Rspec

I was trying to run rspec from a model spec file, but I got this error: "An error occurred in an after hook"
"An error occurred in to after hook PG :: InFailedSqlTransaction:
ERROR: current transaction is aborted, commands ignored until end of
transaction. occurred at C :/ Ruby193/lib/.../postgresql_adapter: 294 "
I googled this issue, and I found a suggestion to downgrade my 'database_cleaner' to '1.0.1'. I did, but it doesn't work.
Does anyone have any idea how to solve this? Thanks in advance!
This can happen if you execute a bad SQL statement in the scope of a transaction, you rescue the exception from that statement, and then try and execute another SQL statement in the same transaction.
Once one statement in a transaction fails no more statements can be executed in that transaction.
Here's an example:
ActiveRecord::Base.transaction do
begin
ActiveRecord::Base.connection.execute "A bad query"
rescue => ex
puts ex.message
end
puts User.count
end
User.count raises PG::InFailedSqlTransaction because the previous SQL statement raised ActiveRecord::StatementInvalid and that was swallowed by the rescue.
So I would look for code that rescues in the scope of a transaction and then tries to run additional SQL statements.

Ruby rescue doesn't catch a StandardError

I'm writing tests for a Ruby Rails application, and I have a block of code that is supposed to catch an error thrown by my Redis server if Ruby cannot connect to it. Currently, the code looks like this:
begin
config.before(:all) { Resque.redis.select 1 }
config.after(:all) { Resque.redis.keys("queue:*").each { |key| Resque.redis.del key } }
rescue Exception
puts "RESCUED REDIS ERROR"
end
According to the stack trace when I try to run the tests, the second line of that code snippet -- config.before(:all) {...} -- throws a Redis::CannotConnectError. After a lot of "e.class.superclass.superclass..." commands, I determined that this error inherited from StandardError.
After that I got stuck. I tried catching the error with "rescue Redis::CannotConnectError", then "rescue", and finally "rescue Exception", but the error is still thrown. However, I tried the same things in the Ruby command prompt, and the exception was caught every time
Could anyone help me work out what's happening here? Thanks!
The problem is that the blocks passed to before and after are not being executed at the time they're defined; instead, they're being stored and then called later by Rspec before and after each spec file runs.
You'll probably want to move the begin/rescue within the blocks instead:
config.before(:all) do
begin
Resque.redis.select 1
rescue Exception
puts "RESCUED REDIS ERROR"
end
end
# same for config.after(:all)

display error message thrown by ms sql in ruby on rails

i've been looking for a solution for weeks now. yet still failed..i have stored procedure that was called using in ruby on rails..in that stored proc i have validations and thrown using raiserror.
ex. raiserror("StartDate must be less than EndDate")
in my ruby on rails controller
def save
begin
M.find_by_sql "EXEC spTestProc '3/15/2010', '3/1/2010'"
rescue Exception => e
render :js => alert(e.message);
end
but instead i get the error message "StartDate must be less than EndDate", I got this error message "DBI::DatabaseError: 37000 (50000) [Microsoft][ODBC SQL Server Driver][SQL Server]StartDate must be less than EndDate..: Exec spTestProc '3/15/2010', '3/1/2010'"
I need to display the error message thrown by my stored proc, but i got some additional message that I dont like to display like "DBI::DatabaseError...etc." how can I do this?
thanks.
Use regular expression to remove the unwanted text.
e.message.gsub(/(^.*SQL Server\])|(: Exec spTestProc.*$)/i, '')
# this will return StartDate must be less than EndDate..

Resources