Rails 4 controller action, Rescue block not working as expected? - ruby-on-rails

Why doesn't this work?? I expect the rescue block to be executed if an ActionView::TemplateError is raised. But that isn't happening for some reason...
The following is a controller action in a rails 4 app.
def categorized
#ActionView::TemplateError raising code
rescue ActionView::TemplateError
binding.pry
end

how about if move exception in application_controller.rb:
rescue_from ActionView::TemplateError do | exception |
binding.pry
end

Try with
rescue => e
bindig.pry
After you that you can check error class with e.class, to make sure you are catching good exception.

Related

rails rescue_from ScriptError

According to the family tree of Exception. SyntaxError is child to ScriptError
I wish to handle Syntax and/or ScriptError in my rails application.
Exception
NoMemoryError
ScriptError
LoadError
NotImplementedError
SyntaxError
SignalException
Interrupt
StandardError
ArgumentError
IOError
EOFError
IndexError
StopIteration
LocalJumpError
NameError
NoMethodError
RangeError
FloatDomainError
RegexpError
RuntimeError
SecurityError
SystemCallError
SystemStackError
ThreadError
TypeError
ZeroDivisionError
SystemExit
fatal
I did:
rescue_from ScriptError, :with => :notify_on_landing_page
but didn't worked.
Error raised on screen :
SyntaxError in Bc::Muse::User::ProfileController#show
I have created an explicit syntax error, it should gracefully rescue it and do the things I want to.
Unfortunately, I don't think it works that way.
Rescuing from exceptions with rescue_from works only after creating a controller instance during request processing (see source code here and here). Your SyntaxError is probably raised much earlier - during autoloading of the given controller and dependent classes / modules. So unless you were trying to rescue from a syntax error of code being loaded during a controller action execution, you are out of luck, I'm afraid.
Test: when you explicitly load a file with a syntax error in a controller action and the rescue_from will work as expected:
class MyController < ApplicationController
rescue_from(::SyntaxError) { Rails.logger.error "SYNTAX ERROR!" }
def index
load "#{Rails.root}/test.rb"
end
end
If you save a test.rb file in the rails root and add a deliberate syntax error in it, you will see the exception is handled correctly by rescue_from and the error message will be present in the log file.
On the other hand, if you look at the full stack trace of your SyntaxError, you will probably see that it does not even reach the ActionController methods for request processing.
Thanks!
I added a middleware to achieve this.
class RescueSyntaxError
def initialize(app)
#app = app
end
def call(env)
#app.call(env)
rescue SyntaxError => error
request = Rack::Request.new(env)
session = request.env['rack.session']
params = request.params
if session.try(:[], :user_object)
##Do validation stuff
...
[302, {'Location' => '/'}, []]
end
end
end

What should return the Grape rescue_from :all block?

The Grape documentation says that:
The rescue_from block must return a Rack::Response object, call error! or re-raise an exception.
but if we use the rescue_from method only to log things and we want to keep the original HTTP answer what should we return ?
If I rethrow the catched exception, it does not keep the original behavior.
For example, some of my tests generate 400 responses but with:
rescue_from :all do |e|
Rails.logger.error(e)
raise e
end
They catch 500 responses.
The better solution I found to reproduce the original behavior is this code:
rescue_from :all do |e|
Rails.logger.error(e)
if e.respond_to?(:status)
error!(e.to_json, e.status, e.headers, e.backtrace)
else
error! "Internal Server Error"
end
end
I should check if the catched exception responds to status because it could be a RuntimeError for example, and RuntimeError does not answer to status.
Am I doing this right ? Or there is a better solution to do that ?
This is answered in https://github.com/ruby-grape/grape/pull/939, pointed from https://github.com/ruby-grape/grape/issues/1300.

Rails: Test against and handle ActionController::InvalidAuthenticityToken

I have a Rails web app with some forms users can use to comment etc. They are frequently being used by spammers trying to create spam comments. Nothing new about that.
Sometimes I get CSRF-hack attempts which causes an ActionController::InvalidAuthenticityToken exception. This happens quite a lot and I would like to rescue and send the user/bot to a "You failed to comment"-page.
This has turned out to be a tricky exception to catch though since I can't recreate the error myself. I first put a rescue in the #create when the model (created by the form) was to be saved but it doesn't catch the exception. In order to do so I consider having it cover the entire controller section but that seems over the top.
My two questions:
Is there a way to re-create an ActionController::InvalidAuthenticityToken error by myself, so I can test it?
When is the exception raised? During .save? On Comment.new? Basically, where should I put my begin/rescue?
Thanks!
You can rescue from this exception in your controller. One way you can set this up is to add a rescue in your ApplicationController.
class ApplicationController < ActionController::Base
rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_auth_token
private
def record_not_found
render :text => "You failed to comment", :status => 422
end
end
You could also just capture the exception locally in your controller action.
def create
begin
# Create your comment
rescue ActionController::InvalidAuthenticityToken
# Render your last view with some error text.
end
end
You can add raise ActionController::InvalidAuthenticityToken inside your action if you want to test it out.

How to Rescue From An Error in Rake

How do I rescue from a
undefined method
error in this code
for user in #users do
#customer = Stripe::Customer.retrieve(user.stripe_customer_token)
if #customer.subscription.nil?
elsif #customer.subscription.plan.id == 2
user.silver_reset
elsif #customer.subscription.plan.id == 3
user.gold_reset
end
end
I have tried a plain rescue call, but rake isn't liking it.
What is way to rescue from the error?
UPDATE:
The way I was doing it
for user in #users do
#customer = Stripe::Customer.retrieve(user.stripe_customer_token)
rescue_from Exception => exception
# Logic
end
if #customer.subscription.nil?
elsif #customer.subscription.plan.id == 2
user.silver_reset
elsif #customer.subscription.plan.id == 3
user.gold_reset
end
end
The Error
/home/user/rails_projects/assignitapp/lib/tasks/daily.rake:25: syntax error, unexpected keyword_rescue, expecting keyword_end
rescue Exception => exception
Rake 0.9.2.2
Rails 3.2.5
Use try to wrap the problem method and return nil if it doesn't exist. E.g.:
unless #customer = Stripe::Customer.try(:retrieve, user.stripe_customer_token)
# Logic
end
Alternatively, this catches more errors:
unless #customer = Stripe::Customer.retrieve(user.stripe_customer_token) rescue nil
# Logic
end
Or this is more what you were trying for:
#users.each do |user|
begin
#customer = Stripe::Customer.retrieve(user.stripe_customer_token)
rescue StandardError => error
# handle error
end
end
I still haven't enough reputation to comment, but regarding the above answer's third option: Don't rescue from Exception!
Exception is the root of Ruby's exception hierarchy, so when you rescue Exception you rescue from everything, including subclasses such as SyntaxError, LoadError, and Interrupt.
If you want to learn more, check out Why is it a bad style to `rescue Exception => e` in Ruby?

RAILS - How deep does assert_raise check for an exception

Should the following test assert an exception was thrown? On my pc it doesn't and I want to know if this is expected behavior.
def a
raise RuntimeError
end
def b
begin
a
rescue RuntimeError
puts "bummer"
end
end
test "assert this" do
assert_raises RuntimeError do
b
end
end
It's an intended behavior. assert_raise doesn't check whether an exception is raised somewhere in the script execution, it checks whether the block raises an uncaught exception of given type.
In other words, it works only if you remove the rescue statement.

Resources