How to rescue timeout issues (Ruby, Rails)
Depending on how you use the library, there are different ways to rescue the exception.
In the library
Assuming you created a wrapper to access some kind of web service, you can have the wrapper rescue the exception and always return a "safe" data.
In the action
If you call a specific method in the action and the method success is a requirement for the action, then you can rescue it in the action.
In the following example I rescue the error and show a specific template to handle the problem.
def action
perform_external_call
rescue Timeout::Error => e
@error = e
render :action => "error"
end
In the controller
If the method call can occur in many different actions, you might want to use rescue_from
.
class TheController < ApplicationController
rescue_from Timeout::Error, :with => :rescue_from_timeout
protected
def rescue_from_timeout(exception)
# code to handle the issue
end
end
rescueing from a timeout error on ruby on rails
I normally like to include all the code in the rescue_from block for readability:
class ApplicationController < ActionController::Base
...
rescue_from Timeout::Error do |e|
## log e if needed
return redirect_to users_root_path
end
...
end
That should work as intended (I don't even know if the return is needed)
rescue Exception not rescuing Timeout::Error in net_http
As you probably know already, calling raise
inside a rescue block will raise the exception to the caller.
Since Timeout::Error
is an Interrupt
in ruby 1.8*, the timeout exception raised by net_http gets handled in the rescue SystemExit, Interrupt
block rather than in the following rescue Exception => e
.
To verify that Timeout::Error
is an Interrupt, just evaluate Timeout::Error.ancestors
. What you get out of that is the hierarchy of classes Timeout::Error inherits from.
*this is no longer the case in ruby1.9.
Ruby Timeout::timeout doesn't fire Exception and doesn't return what documented
Your code is correct
require 'timeout'
begin
complete_results = Timeout.timeout(1) do
sleep(2)
end
rescue Timeout::Error
puts 'Print me something please'
end
does print out "print me something please".
Try the basic code as above. If that works, you have an issue in platform.search
.
Rescue_from doesn't rescue Timeout::Error from views or helpers
I ran into the same problem. I'm using Rails 3 + Rack::Timeout and trying to rescue_from in ApplicationController.
I ended up using this ...
rescue_from Exception do |exception|
if exception.is_a?(Timeout::Error) || /execution expired/ =~ exception.message
# rescued from timeout error
end
raise
end
UPDATE
I patched the rack-timeout gem to properly return Timeout::Error. It was a threading issue. Official gem has been updated: https://github.com/kch/rack-timeout
The new preferred method is below. In general, it's not a great idea to rescue from Exception and should be avoided if possible.
class ApplicationController < ActionController::Base
rescue_from Timeout::Error, with: :handle_timeout
def handle_timeout(exception)
# handle timeout error
end
end
Handling Timeout error
Well, that's expected behaviour of Timeout
. If the block takes too long, its execution gets terminated and an exception thrown.
You would probably like to catch the exception and handle it appropriately:
require 'timeout'
begin
status = Timeout::timeout(5) {
# Something that should be interrupted if it takes too much time...
}
rescue Timeout::Error
puts 'That took too long, exiting...'
end
Related Topics
Why Do I Get "Including Capybara::Dsl in the Global Scope Is Not Recommended!"
Rails: Update Model Attribute Without Invoking Callbacks
In a Sinatra App on Heroku, Session Is Not Shared Across Dynos
Is There a Ruby Http Client Library with a Response Cache
Run Code Only If Script Called from the Command Line
How to Fix Libv8 Error from Gemfile on Mavericks
Alias_Method and Class_Methods Don't Mix
Best Way to Work with Large Amounts of CSV Data Quickly
What's the Cleanest Way to Override Activerecord's Find for Both Models and Collections
How to Tell or Hint to Rubymine What Type a Local or Instance Variable Is