How do I handle errors when using api_auth gem? - ruby-on-rails

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!

Related

Is there a list of JSON parse error codes?

I'm trying to provide a good experience to users that are using JSON and the parser is on the backend (Ruby).
Most of the time, when you get a badly formatted JSON payload the error is of the format XXX unexpected token at '<entire payload here>'. That's not very user-friendly nor practical.
My question is: Is there a list of the XXX error codes that could help create better error messages that could be understood by beginners and not-really-tech-people?
Thanks!
XXX in this kind of errors is not a special code of the error. It is just a line number from the file where this error was raised. For example, for Ruby 2.5.1 you'll get JSON::ParserError (765: unexpected token at https://github.com/ruby/ruby/blob/v2_5_1/ext/json/parser/parser.rl#L765
You can find a list in the documentation for the module.
Think this covers it:
JSON::JSONError
JSON::GeneratorError
JSON::GenericObject
# The base exception for JSON errors.
JSON::MissingUnicodeSupport
# This exception is raised if the required unicode support is missing on the system. Usually this means that the iconv library is not installed.
JSON::NestingError
# This exception is raised if the nesting of parsed data structures is too deep.
JSON::ParserError
# This exception is raised if a parser error occurs.
JSON::UnparserError
# This exception is raised if a generator or unparser error occurs.
JSON::JSONError is the parent class, so you can rescue from that and provide per-error-class messages as needed.
I feel it's worth noting that in my experience the vast majority of errors relating to JSON are of the class JSON::ParserError. Another common issue worth considering is getting ArgumentError if nil is passed as an argument.
As an example of how this could be used, you could work with something like the following:
begin
JSON.parse(your_json)
rescue JSON::JSONError, ArgumentError => e
{ error: I18n.t(e.to_s) } # <- or whatever you want to do per error
end
Hope that helps - let me know how you get on :)

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

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)

Begin Rescue not catching error

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.

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