Rails: rescue_from and rethrow - ruby-on-rails

I want to track my user's exception with mixpanel so I added this code in my application_controller:
class ApplicationController < ActionController::Base
rescue_from Exception do |exception|
if Rails.env.production?
tracker.track(session[:mixpanel_unauth_id], 'Exception', {:exception => exception.to_s})
rescue_action_without_handler(exception)
end
end
I just want to intercept the error for mixpanel than the error must be re thrown normally.
In production a have a method not found error on rescue_action_without_handler
In development I have a blank white page when an error happen.
How to solve this problem?
I use Rails 3.2

Related

Precedence of error handlers: rescue_from vs rescue in a method

In my application_controller.rb I have the following line
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
Now, in one method, I would like to handle that specific error differently and I've added this to one method in a controller.
class MyClass < ApplicationController
def my_method
# raising the Pundit::NotAuthorizedError in the method
authorize resource, :my_method?
rescue Pundit::NotAuthorizedError
# code on how to deal with the error
end
end
If I execute the code, the error handler from application_controller.rb will be handling my error instead of the error handler in the method.
So my question is, what is the precedence of the error handlers and is there any way I can change this, so that the error is handled in the method and not globally?
Please forget my previous answer, I myself made a mistake when reproducing your issue. In deed I am not able to reproduce it.
Please have a look at this little demo app I created:
https://github.com/andi-dev/rescue-handler-demo/blob/master/app/controllers/peas_controller.rb
The rescue_from handler is not executed, and the browser shows what I render from the rescue block within the action-method.

Need a handler. Pass the with: keyword argument or provide a block

Recently I update my app from Ruby version 2.6.1 to 3.0.1 & I'm using rbenv as a version manager.
but when I try to run the rails server I got an error
=> Booting Puma
=> Rails 6.1.3 application starting in development
=> Run `bin/rails server --help` for more startup options
Exiting
/home/humayun/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activesupport-6.1.3/lib/active_support/rescuable.rb:56:in `rescue_from': Need a handler. Pass the with: keyword argument or provide a block. (ArgumentError)
from /home/humayun/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/will_paginate-3.1.8/lib/will_paginate/railtie.rb:67:in `rescue_from'
from /home/humayun/umerfarooq/Alchemy/app/controllers/application_controller.rb:2:in `<class:ApplicationController>'
from /home/humayun/umerfarooq/Alchemy/app/controllers/application_controller.rb:1:in `<main>'
I just read Here about the function which is causing an error on line 56.
applciation_controller.rb
rescue_from Exception, with: :handle_exception
protect_from_forgery prepend: true, with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :initialize_api
def not_found
raise ActionController::RoutingError.new('Not Found')
end
def handle_exception(exception = nil)
return render_404 if [ActionController::RoutingError, ActiveRecord::RecordNotFound].include?(exception.class)
render_500
end
I think this is because of depreciation.
can anyone please tell me how to handle these errors?
your handle_exception probably will need a block that render a view or returns a status
as mentioned in the error in app/controllers/application_controller.rb:2 you probably have a rescue_from without an error or a handler you need to follow any of below syntax
class ApplicationController < ActionController::Base
rescue_from User::NotAuthorized, with: :deny_access # self defined exception
rescue_from ActiveRecord::RecordInvalid, with: :show_errors
rescue_from 'MyAppError::Base' do |exception|
render xml: exception, status: 500
end
private
def deny_access
...
end
def show_errors(exception)
exception.record.new_record? ? ...
end
end
as per documentation here https://apidock.com/rails/ActiveSupport/Rescuable/ClassMethods/rescue_from
------- Update:
This is due to the will_paginate gem that you are using that overrides the rescue_from method in your controller alongside the new ruby updates that change the behavior around the keyword attribute
if your base controller include ControllerRescuePatch you might be able to remove it and this will fix it but not sure what will happen to your pagination.
Otherwise, hold off the ruby update until the will_paginate update their code to fix this

Rails - Execute javascript code on cancan access denied

Let's say I have a rescue code on my application controller for handling access denied from cancan, like this:
class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |exception|
#handle the exception
end
end
What I would like to do is, when the exception is raised, to show a popup to the user. But for that I should run a javascript code. How could I achieve that? Thanks in advance!

How can I show 404 error page instead of routing error?

In my Ruby on Rails application I want to show 404 error page instead of routing error when the given route does not matches or exists in my application. Can anybody help me to make it possible?
If you cannot easily run production mode locally, set the consider_all_requests_local to false in your config/environments/development.rb file.
This is already the default behavior in production. In development environment routing errors are displayed to let the developer notice them and fix them.
If you want to try it, start the server in production mode and check it.
$ script/rails s -e production
in ApplicationController
rescue_from ActiveRecord::RecordNotFound, :with => :rescue404
rescue_from ActionController::RoutingError, :with => :rescue404
def rescue404
#your custom method for errors, you can render anything you want there
end
This return 404 page
In ApplicationController
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :route_not_found
rescue_from ActionController::RoutingError, with: :route_not_found
rescue_from ActionController::UnknownFormat, with: :route_not_found
def route_not_found
render file: Rails.public_path.join('404.html'), status: :not_found, layout: false
end
You could catch exception that is thrown when a route is not found and then render a custom page. Let me know if you need help with the code. There might be many other ways to do this but this definitely works.

Can I execute a method everytime I get an exception on Rails 3?

I tried almost everything on web, all I want is to call a method whenever an exception like "ActiveRecord::RecordNotFound" or "No route matches" appears.
Rescues from ApplicationController does not work, but why?
class ApplicationController < ActionController::Base
protect_from_forgery
private
def self.send_report_error(message)
Notifier.page_failure(message).deliver
end
rescue ActiveRecord::RecordNotFound
# handle not found error
send_report_error ActiveRecord::RecordNotFound.to_s
rescue ActiveRecord::ActiveRecordError
# handle other ActiveRecord errors
send_report_error ActiveRecord::ActiveRecordError.to_s
rescue # StandardError
# handle most other errors
send_report_error "common error"
rescue Exception
# handle everything else
send_report_error "common exception"
end
Use rescue_from. For example:
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, :with => :send_report_error
end
http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html

Resources