How to catch base exception class in Ruby on Rails?

542 views
Skip to first unread message

Romiras

unread,
Jun 27, 2016, 9:05:50 AM6/27/16
to Ruby on Rails: Talk

I'd like to catch any RoR exceptions in REST API application with 'rescue_from'.


rescue_from
StandardError do |exception| message = Rails.env.production? ? 'API server error' : exception.message render json: {status: "Error", message: message}, status: :internal_server_error end


but it catches too much irrelevant exceptions. Can I catch RoR exceptions only? Is it a good practice at all? If not, what else you can recommend?

radhames brito

unread,
Jun 28, 2016, 9:16:40 PM6/28/16
to Ruby on Rails: Talk
This is actually a very bad practice, you are actually creating a black hole that will swallow many relevant problems and will be super hard to debug and maintain in the future. What you want to do is only catch error that you can handle, do not catch everything, you actually have to let most raise and have 2 things: 1) generic message for the users and 2) errors notification system that will send technical details to you and your team, have a look at https://github.com/airbrake/airbrake and get documentation about it. If you want more help, please be more specific about what you want to achieve.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/3552a5a5-0bb7-424e-ac75-f8d4c9771198%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Romiras

unread,
Jun 29, 2016, 3:23:06 AM6/29/16
to Ruby on Rails: Talk
A communication with API server made with JSON.
In case of application error instead of crashing with status 500 with HTML response I'd like that API clients will receive response with generic error message
{status: "Error", message: "API server error"}
or may be something more specific in some cases.

Of course, any application error should be reported to developer via Airbrake or similar gem:

Just for sake of clarity here is excerpt of that Airbrake suggests:

begin
  params = {
     # params that you pass to a method that can throw an exception
  }
  my_unpredicable_method(params)
rescue => e
  Airbrake.notify_or_ignore(
   e,
   parameters: params,
   cgi_data: ENV.to_hash
  )
end

In code above they assume that application catches every descendant of StandardError. Is that good or bad practice?

radhames brito

unread,
Jun 29, 2016, 7:41:45 AM6/29/16
to Ruby on Rails: Talk
In this case, if you are using Airbrake you can let it catch all, because the purpose of exceptions it to notify and inform the developers, otherwise the program would just crash and stop running without providing any information of what happen. The problem with the previous code block you had was that it was returning ```json: {status: "Error", message: message}``` to everything and not notifying the developers with the technical information of the error, that is a bad practice.

In any case if you are setting your content headers correctly in the AJAX request the server will not respond with an HTML page it will return status code 500 for the AJAX request without you needing to do anything, and if you are using https://github.com/airbrake/airbrake it is already integrated with rails so you dont need to set up that code block and you dont need to setup the environment condition like that, Airbrake.configure can have ignore_environments = %w(development test) . I think your problem might be more related to how you are setting up your ajax request.


Now I think that you should still be more specific, for example, if you are performing a save operation in the my_unpredicable_method(params) you might want to do

begin
  complex_operation_that_calls_save!_internally
rescue ActiveRecord::ReadOnlyRecord => invalid
  puts invalid.record.errors
end

if its connection errors then have a look at

begin
  response = Net::HTTP.post_form(...) # or any Net::HTTP call
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
       Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
  ...
end

Is even to that, for your own procedures you create your own exception classes

class InvalidModifyType < StandardError; end

The more specific you are the more control you will have, the easier it will be to maintain and debug.


--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages