Add better error messages for rate limits.

This commit is contained in:
Robin Ward 2015-09-24 13:52:32 -04:00
parent 3620c8c85e
commit 0b4cb5cf0d
4 changed files with 34 additions and 5 deletions

View File

@ -377,6 +377,17 @@ en:
rate_limiter:
slow_down: "You have performed this action too many times, try again later"
too_many_requests: "We have a daily limit on how many times that action can be taken. Please wait %{time_left} before trying again."
by_type:
first_day_replies_per_day: "You've reached the maximum number of posts a user can post on their first day. Please wait %{time_left} before trying again."
first_day_topics_per_day: "You've reached the maximum number of topics a user can post on their first day. Please wait %{time_left} before trying again."
topics_per_day: "You've posted too many topics today. Please wait %{time_left} before trying again."
create_topic: "You're posting topics too quickly. Please wait %{time_left} before trying again."
create_post: "You're replying too quickly. Please wait %{time_left} before trying again."
pms_per_day: "You've sent too many messages today. Please wait %{time_left} before trying again."
create_like: "You've liked too many posts today. Please wait %{time_left} before trying again."
create_bookmark: "You've bookmarked too many posts today. Please wait %{time_left} before trying again."
edit_post: "You've edited too many posts today. Please wait %{time_left} before trying again."
hours:
one: "1 hour"
other: "%{count} hours"

View File

@ -1,6 +1,10 @@
require 'rate_limiter'
class EditRateLimiter < RateLimiter
def initialize(user)
super(user, "edit-post:#{Date.today}", SiteSetting.max_edits_per_day, 1.day.to_i)
super(user, "edit-post", SiteSetting.max_edits_per_day, 1.day.to_i)
end
def build_key(type)
"#{super(type)}:#{Date.today}"
end
end

View File

@ -27,9 +27,14 @@ class RateLimiter
$redis.delete_prefixed(RateLimiter.key_prefix)
end
def initialize(user, key, max, secs)
def build_key(type)
"#{RateLimiter.key_prefix}:#{@user && @user.id}:#{type}"
end
def initialize(user, type, max, secs)
@user = user
@key = "#{RateLimiter.key_prefix}:#{@user && @user.id}:#{key}"
@type = type
@key = build_key(type)
@max = max
@secs = secs
end
@ -53,7 +58,7 @@ class RateLimiter
# let's ensure we expire this key at some point, otherwise we have leaks
$redis.expire(@key, @secs * 2)
else
raise LimitExceeded.new(seconds_to_wait)
raise RateLimiter::LimitExceeded.new(seconds_to_wait, @type)
end
end

View File

@ -3,11 +3,13 @@ class RateLimiter
# A rate limit has been exceeded.
class LimitExceeded < StandardError
def initialize(available_in)
def initialize(available_in, type=nil)
@available_in = available_in
@type = type
end
def description
time_left = ""
if @available_in < 1.minute.to_i
time_left = I18n.t("rate_limiter.seconds", count: @available_in)
@ -16,6 +18,13 @@ class RateLimiter
else
time_left = I18n.t("rate_limiter.hours", count: (@available_in / 1.hour.to_i))
end
if @type.present?
type_key = @type.gsub(/-/, '_')
msg = I18n.t("rate_limiter.by_type.#{type_key}", time_left: time_left, default: "")
return msg if msg.present?
end
I18n.t("rate_limiter.too_many_requests", time_left: time_left)
end
end