mirror of
https://github.com/mastodon/mastodon.git
synced 2024-08-20 21:08:15 -07:00
Wrap common http-level errors into constant
This commit is contained in:
parent
2ed13071ef
commit
70deaee948
23 changed files with 41 additions and 28 deletions
|
@ -32,7 +32,7 @@ class ApplicationController < ActionController::Base
|
||||||
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
|
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
|
||||||
rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests
|
rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests
|
||||||
|
|
||||||
rescue_from HTTP::Error, OpenSSL::SSL::SSLError, with: :internal_server_error
|
rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, with: :internal_server_error)
|
||||||
rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight, ActiveRecord::SerializationFailure, with: :service_unavailable
|
rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight, ActiveRecord::SerializationFailure, with: :service_unavailable
|
||||||
|
|
||||||
rescue_from Seahorse::Client::NetworkingError do |e|
|
rescue_from Seahorse::Client::NetworkingError do |e|
|
||||||
|
|
|
@ -20,14 +20,14 @@ module Api::ErrorHandling
|
||||||
render json: { error: 'Record not found' }, status: 404
|
render json: { error: 'Record not found' }, status: 404
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
|
|
||||||
render json: { error: 'Remote data could not be fetched' }, status: 503
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue_from OpenSSL::SSL::SSLError do
|
rescue_from OpenSSL::SSL::SSLError do
|
||||||
render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
|
render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS) do
|
||||||
|
render json: { error: 'Remote data could not be fetched' }, status: 503
|
||||||
|
end
|
||||||
|
|
||||||
rescue_from Mastodon::NotPermittedError do
|
rescue_from Mastodon::NotPermittedError do
|
||||||
render json: { error: 'This action is not allowed' }, status: 403
|
render json: { error: 'This action is not allowed' }, status: 403
|
||||||
end
|
end
|
||||||
|
|
|
@ -80,12 +80,12 @@ module SignatureVerification
|
||||||
fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature']
|
fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature']
|
||||||
rescue SignatureVerificationError => e
|
rescue SignatureVerificationError => e
|
||||||
fail_with! e.message
|
fail_with! e.message
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError => e
|
|
||||||
fail_with! "Failed to fetch remote data: #{e.message}"
|
|
||||||
rescue Mastodon::UnexpectedResponseError
|
rescue Mastodon::UnexpectedResponseError
|
||||||
fail_with! 'Failed to fetch remote data (got unexpected reply from server)'
|
fail_with! 'Failed to fetch remote data (got unexpected reply from server)'
|
||||||
rescue Stoplight::Error::RedLight
|
rescue Stoplight::Error::RedLight
|
||||||
fail_with! 'Fetching attempt skipped because of recent connection failure'
|
fail_with! 'Fetching attempt skipped because of recent connection failure'
|
||||||
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||||
|
fail_with! "Failed to fetch remote data: #{e.message}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def request_body
|
def request_body
|
||||||
|
|
|
@ -13,7 +13,7 @@ class MediaProxyController < ApplicationController
|
||||||
rescue_from ActiveRecord::RecordInvalid, with: :not_found
|
rescue_from ActiveRecord::RecordInvalid, with: :not_found
|
||||||
rescue_from Mastodon::UnexpectedResponseError, with: :not_found
|
rescue_from Mastodon::UnexpectedResponseError, with: :not_found
|
||||||
rescue_from Mastodon::NotPermittedError, with: :not_found
|
rescue_from Mastodon::NotPermittedError, with: :not_found
|
||||||
rescue_from HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, with: :internal_server_error
|
rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, with: :internal_server_error)
|
||||||
|
|
||||||
def show
|
def show
|
||||||
with_redis_lock("media_download:#{params[:id]}") do
|
with_redis_lock("media_download:#{params[:id]}") do
|
||||||
|
|
|
@ -279,7 +279,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
media_attachment.download_file!
|
media_attachment.download_file!
|
||||||
media_attachment.download_thumbnail!
|
media_attachment.download_thumbnail!
|
||||||
media_attachment.save
|
media_attachment.save
|
||||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id)
|
RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id)
|
||||||
rescue Seahorse::Client::NetworkingError => e
|
rescue Seahorse::Client::NetworkingError => e
|
||||||
Rails.logger.warn "Error storing media attachment: #{e}"
|
Rails.logger.warn "Error storing media attachment: #{e}"
|
||||||
|
|
|
@ -35,7 +35,7 @@ class AccountAlias < ApplicationRecord
|
||||||
def set_uri
|
def set_uri
|
||||||
target_account = ResolveAccountService.new.call(acct)
|
target_account = ResolveAccountService.new.call(acct)
|
||||||
self.uri = ActivityPub::TagManager.instance.uri_for(target_account) unless target_account.nil?
|
self.uri = ActivityPub::TagManager.instance.uri_for(target_account) unless target_account.nil?
|
||||||
rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error
|
rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
# Validation will take care of it
|
# Validation will take care of it
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ class AccountMigration < ApplicationRecord
|
||||||
|
|
||||||
def set_target_account
|
def set_target_account
|
||||||
self.target_account = ResolveAccountService.new.call(acct, skip_cache: true)
|
self.target_account = ResolveAccountService.new.call(acct, skip_cache: true)
|
||||||
rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError
|
rescue Webfinger::Error, Mastodon::Error, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
# Validation will take care of it
|
# Validation will take care of it
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ module Remotable
|
||||||
|
|
||||||
public_send(:"#{attachment_name}=", ResponseWithLimit.new(response, limit))
|
public_send(:"#{attachment_name}=", ResponseWithLimit.new(response, limit))
|
||||||
end
|
end
|
||||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||||
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
|
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
|
||||||
public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present?
|
public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present?
|
||||||
raise e unless suppress_errors
|
raise e unless suppress_errors
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Form::Redirect
|
||||||
|
|
||||||
def set_target_account
|
def set_target_account
|
||||||
@target_account = ResolveAccountService.new.call(acct, skip_cache: true)
|
@target_account = ResolveAccountService.new.call(acct, skip_cache: true)
|
||||||
rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError
|
rescue Webfinger::Error, Mastodon::Error, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
# Validation will take care of it
|
# Validation will take care of it
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ class RemoteFollow
|
||||||
|
|
||||||
def acct_resource
|
def acct_resource
|
||||||
@acct_resource ||= webfinger!("acct:#{acct}")
|
@acct_resource ||= webfinger!("acct:#{acct}")
|
||||||
rescue Webfinger::Error, HTTP::ConnectionError
|
rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -127,13 +127,13 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
begin
|
begin
|
||||||
@account.avatar_remote_url = image_url('icon') || '' unless skip_download?
|
@account.avatar_remote_url = image_url('icon') || '' unless skip_download?
|
||||||
@account.avatar = nil if @account.avatar_remote_url.blank?
|
@account.avatar = nil if @account.avatar_remote_url.blank?
|
||||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
RedownloadAvatarWorker.perform_in(rand(30..600).seconds, @account.id)
|
RedownloadAvatarWorker.perform_in(rand(30..600).seconds, @account.id)
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
@account.header_remote_url = image_url('image') || '' unless skip_download?
|
@account.header_remote_url = image_url('image') || '' unless skip_download?
|
||||||
@account.header = nil if @account.header_remote_url.blank?
|
@account.header = nil if @account.header_remote_url.blank?
|
||||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
RedownloadHeaderWorker.perform_in(rand(30..600).seconds, @account.id)
|
RedownloadHeaderWorker.perform_in(rand(30..600).seconds, @account.id)
|
||||||
end
|
end
|
||||||
@account.statuses_count = outbox_total_items if outbox_total_items.present?
|
@account.statuses_count = outbox_total_items if outbox_total_items.present?
|
||||||
|
@ -276,7 +276,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
|
total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
|
||||||
has_first_page = collection.is_a?(Hash) && collection['first'].present?
|
has_first_page = collection.is_a?(Hash) && collection['first'].present?
|
||||||
@collections[type] = [total_items, has_first_page]
|
@collections[type] = [total_items, has_first_page]
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::LengthValidationError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
@collections[type] = [nil, nil]
|
@collections[type] = [nil, nil]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
||||||
media_attachment.download_file! if media_attachment.remote_url_previously_changed?
|
media_attachment.download_file! if media_attachment.remote_url_previously_changed?
|
||||||
media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed?
|
media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed?
|
||||||
media_attachment.save
|
media_attachment.save
|
||||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id)
|
RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id)
|
||||||
rescue Seahorse::Client::NetworkingError => e
|
rescue Seahorse::Client::NetworkingError => e
|
||||||
Rails.logger.warn "Error storing media attachment: #{e}"
|
Rails.logger.warn "Error storing media attachment: #{e}"
|
||||||
|
|
|
@ -29,7 +29,7 @@ class FetchLinkCardService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
attach_card if @card&.persisted?
|
attach_card if @card&.persisted?
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, EncodingError, ActiveRecord::RecordInvalid => e
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS, EncodingError, ActiveRecord::RecordInvalid => e
|
||||||
Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" }
|
Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" }
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ class FetchResourceService < BaseService
|
||||||
return if url.blank?
|
return if url.blank?
|
||||||
|
|
||||||
process(url)
|
process(url)
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||||
Rails.logger.debug { "Error fetching resource #{@url}: #{e}" }
|
Rails.logger.debug { "Error fetching resource #{@url}: #{e}" }
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -115,7 +115,7 @@ class ImportService < BaseService
|
||||||
next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri)
|
next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri)
|
||||||
|
|
||||||
status || ActivityPub::FetchRemoteStatusService.new.call(uri)
|
status || ActivityPub::FetchRemoteStatusService.new.call(uri)
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
nil
|
nil
|
||||||
rescue => e
|
rescue => e
|
||||||
Rails.logger.warn "Unexpected error when importing bookmark: #{e}"
|
Rails.logger.warn "Unexpected error when importing bookmark: #{e}"
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Keys::ClaimService < BaseService
|
||||||
return unless json.present? && json['publicKeyBase64'].present?
|
return unless json.present? && json['publicKeyBase64'].present?
|
||||||
|
|
||||||
@result = Result.new(@target_account, @device_id, key_id: json['id'], key: json['publicKeyBase64'], signature: json.dig('signature', 'signatureValue'))
|
@result = Result.new(@target_account, @device_id, key_id: json['id'], key: json['publicKeyBase64'], signature: json.dig('signature', 'signatureValue'))
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::Error => e
|
||||||
Rails.logger.debug { "Claiming one-time key for #{@target_account.acct}:#{@device_id} failed: #{e}" }
|
Rails.logger.debug { "Claiming one-time key for #{@target_account.acct}:#{@device_id} failed: #{e}" }
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Keys::QueryService < BaseService
|
||||||
@devices = as_array(json['items']).map do |device|
|
@devices = as_array(json['items']).map do |device|
|
||||||
Device.new(device_id: device['id'], name: device['name'], identity_key: device.dig('identityKey', 'publicKeyBase64'), fingerprint_key: device.dig('fingerprintKey', 'publicKeyBase64'), claim_url: device['claim'])
|
Device.new(device_id: device['id'], name: device['name'], identity_key: device.dig('identityKey', 'publicKeyBase64'), fingerprint_key: device.dig('fingerprintKey', 'publicKeyBase64'), claim_url: device['claim'])
|
||||||
end
|
end
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::Error => e
|
||||||
Rails.logger.debug { "Querying devices for #{@account.acct} failed: #{e}" }
|
Rails.logger.debug { "Querying devices for #{@account.acct} failed: #{e}" }
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -44,7 +44,7 @@ class ProcessMentionsService < BaseService
|
||||||
if mention_undeliverable?(mentioned_account)
|
if mention_undeliverable?(mentioned_account)
|
||||||
begin
|
begin
|
||||||
mentioned_account = ResolveAccountService.new.call(Regexp.last_match(1))
|
mentioned_account = ResolveAccountService.new.call(Regexp.last_match(1))
|
||||||
rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError
|
rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
mentioned_account = nil
|
mentioned_account = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ class SoftwareUpdateCheckService < BaseService
|
||||||
Request.new(:get, "#{api_url}?version=#{version}").add_headers('Accept' => 'application/json', 'User-Agent' => 'Mastodon update checker').perform do |res|
|
Request.new(:get, "#{api_url}?version=#{version}").add_headers('Accept' => 'application/json', 'User-Agent' => 'Mastodon update checker').perform do |res|
|
||||||
return Oj.load(res.body_with_limit, mode: :strict) if res.code == 200
|
return Oj.load(res.body_with_limit, mode: :strict) if res.code == 200
|
||||||
end
|
end
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Oj::ParseError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS, Oj::ParseError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ class VerifyLinkService < BaseService
|
||||||
return unless link_back_present?
|
return unless link_back_present?
|
||||||
|
|
||||||
field.mark_verified!
|
field.mark_verified!
|
||||||
rescue OpenSSL::SSL::SSLError, HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, IPAddr::AddressFamilyError => e
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||||
Rails.logger.debug { "Error fetching link #{@url}: #{e}" }
|
Rails.logger.debug { "Error fetching link #{@url}: #{e}" }
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ class RefollowWorker
|
||||||
# Schedule re-follow
|
# Schedule re-follow
|
||||||
begin
|
begin
|
||||||
FollowService.new.call(follower, target_account, reblogs: reblogs, notify: notify, languages: languages, bypass_limit: true)
|
FollowService.new.call(follower, target_account, reblogs: reblogs, notify: notify, languages: languages, bypass_limit: true)
|
||||||
rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, Mastodon::UnexpectedResponseError, HTTP::Error, OpenSSL::SSL::SSLError
|
rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,4 +35,17 @@ module Mastodon
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
HTTP_CONNECTION_ERRORS = [
|
||||||
|
Addressable::URI::InvalidURIError,
|
||||||
|
HTTP::ConnectionError,
|
||||||
|
HTTP::Error,
|
||||||
|
HTTP::TimeoutError,
|
||||||
|
IPAddr::AddressFamilyError,
|
||||||
|
Mastodon::HostValidationError,
|
||||||
|
Mastodon::LengthValidationError,
|
||||||
|
Mastodon::PrivateNetworkAddressError,
|
||||||
|
Mastodon::UnexpectedResponseError,
|
||||||
|
OpenSSL::SSL::SSLError,
|
||||||
|
].freeze
|
||||||
end
|
end
|
||||||
|
|
|
@ -305,7 +305,7 @@ module Mastodon::CLI
|
||||||
|
|
||||||
begin
|
begin
|
||||||
code = Request.new(:head, account.uri).perform(&:code)
|
code = Request.new(:head, account.uri).perform(&:code)
|
||||||
rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Mastodon::PrivateNetworkAddressError
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
skip_domains << account.domain
|
skip_domains << account.domain
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue