Processing rack_throttle exceptions in rails application
Asked Answered
L

2

2

How can i process errors generated by rack-throttle gem when rate limit is excedeed? Now i just get a response containing the following:

Internal Server Error

undefined method `each' for "403 Forbidden (Rate Limit Exceeded)\n":String

Here is the stack trace

ERROR NoMethodError: undefined method `each' for "403 Forbidden (Rate Limit Exceeded)\n":String
/home/rkapitonov/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.1.1/lib/active_record/query_cache.rb:45:in `each'
/home/rkapitonov/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:458:in `each'
/home/rkapitonov/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.6/lib/rack/body_proxy.rb:23:in `method_missing'
/home/rkapitonov/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.1/lib/rails/rack/content_length.rb:26:in `call'
/home/rkapitonov/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.1/lib/rails/rack/log_tailer.rb:14:in `call'
/home/rkapitonov/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.6/lib/rack/handler/webrick.rb:59:in `service'
/home/rkapitonov/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/home/rkapitonov/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/home/rkapitonov/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

How can i process this error and render some custom file or make a redirect?

Latea answered 12/3, 2012 at 10:45 Comment(0)
L
8

Finally i found a solution

The problem was in rack-throttle gem. Response body should be an array of strings, so to fix the issue i've just overridden http_error method and that did the trick for me. You should make http_status(code) + (message.nil? ? "\n" : " (#{message})\n") an array so just take it in square brackets.

class Rack::Throttle::Limiter
  def http_error(code, message = nil, headers = {})
    [code, {'Content-Type' => 'text/plain; charset=utf-8'}.merge(headers),
    [http_status(code) + (message.nil? ? "\n" : " (#{message})\n")]]
  end
end

Put this inside config/initializers/rack_throttle.rb. The name of the file may be changed to whatever you like.

Latea answered 15/3, 2012 at 14:37 Comment(3)
For those looking for copy & paste: put this inside class Rack::Throttle::Limiter in an initializer file, like rack_throttle.rbBath
or use this fork of rack-throttle that fixes it: github.com/datagraph/rack-throttle/pull/6Dara
I suggest using the solution by Magne. The original repo seems to be abandoned.Isomeric
O
0

You need create a Rack::Middleware to check if there are an exceed limit from rack-throttle and do what you want.

Or you can override the method Rack::Throttle::Limiter#rate_limit_exceeded to do what you really want : https://github.com/datagraph/rack-throttle/blob/master/lib/rack/throttle/limiter.rb#L177

You can pass some option In your Rack::Trottle middelware too :

https://github.com/datagraph/rack-throttle/blob/master/lib/rack/throttle/limiter.rb#L19

Occultation answered 12/3, 2012 at 11:19 Comment(1)
well, i still can't redirect from middleware. I also can't render anything from there.Latea

© 2022 - 2024 — McMap. All rights reserved.