[deploy] handle rate limit errors gracefully (#7422)
This commit is contained in:
parent
27131f6f42
commit
de88a08ebd
6 changed files with 31 additions and 1 deletions
|
|
@ -21,6 +21,8 @@ class Api::V0::ApiController < ApplicationController
|
|||
error_unauthorized
|
||||
end
|
||||
|
||||
rescue_from RateLimitChecker::LimitReached, with: :too_many_requests
|
||||
|
||||
protected
|
||||
|
||||
def error_unprocessable_entity(message)
|
||||
|
|
@ -35,6 +37,10 @@ class Api::V0::ApiController < ApplicationController
|
|||
render json: { error: "not found", status: 404 }, status: :not_found
|
||||
end
|
||||
|
||||
def too_many_requests
|
||||
render json: { error: "too many requests", status: 429 }, status: :too_many_requests
|
||||
end
|
||||
|
||||
def authenticate!
|
||||
if doorkeeper_token
|
||||
@user = User.find(doorkeeper_token.resource_owner_id)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class RateLimitChecker
|
|||
|
||||
class UploadRateLimitReached < StandardError; end
|
||||
class DailyFollowAccountLimitReached < StandardError; end
|
||||
class LimitReached < StandardError; end
|
||||
|
||||
def limit_by_action(action)
|
||||
check_method = "check_#{action}_limit"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module Articles
|
|||
end
|
||||
|
||||
def call
|
||||
raise if RateLimitChecker.new(user).limit_by_action("published_article_creation")
|
||||
raise RateLimitChecker::LimitReached if RateLimitChecker.new(user).limit_by_action("published_article_creation")
|
||||
|
||||
article = save_article
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Honeybadger.configure do |config|
|
|||
Pundit::NotAuthorizedError,
|
||||
ActiveRecord::RecordNotFound,
|
||||
ActiveRecord::QueryCanceled,
|
||||
RateLimitChecker::LimitReached,
|
||||
]
|
||||
config.request.filter_keys += %w[authorization]
|
||||
config.sidekiq.attempt_threshold = 10
|
||||
|
|
|
|||
|
|
@ -445,6 +445,15 @@ RSpec.describe "Api::V0::Articles", type: :request do
|
|||
let_it_be(:api_secret) { create(:api_secret) }
|
||||
let_it_be(:user) { api_secret.user }
|
||||
|
||||
context "when creation limit is reached" do
|
||||
it "returns a 429 status code and error" do
|
||||
allow(Articles::Creator).to receive(:call).and_raise(RateLimitChecker::LimitReached)
|
||||
headers = { "api-key" => api_secret.secret, "content-type" => "application/json" }
|
||||
post api_articles_path, params: { article: { body_markdown: "" } }.to_json, headers: headers
|
||||
expect(response).to have_http_status(:too_many_requests)
|
||||
end
|
||||
end
|
||||
|
||||
context "when unauthorized" do
|
||||
it "fails with no api key" do
|
||||
post api_articles_path, headers: { "content-type" => "application/json" }
|
||||
|
|
|
|||
|
|
@ -218,4 +218,17 @@ RSpec.describe "Articles", type: :request do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /create" do
|
||||
before { sign_in user }
|
||||
|
||||
context "when creation limit is reached" do
|
||||
it "raises a rate limit reached error" do
|
||||
allow(Articles::Creator).to receive(:call).and_raise(RateLimitChecker::LimitReached)
|
||||
expect do
|
||||
post articles_path, params: { article: { markdown: "123" } }
|
||||
end.to raise_error(RateLimitChecker::LimitReached)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue