diff --git a/app/controllers/api/v1/donation_campaigns_controller.rb b/app/controllers/api/v1/donation_campaigns_controller.rb index 4b3d680e9aa..43df1fdc3eb 100644 --- a/app/controllers/api/v1/donation_campaigns_controller.rb +++ b/app/controllers/api/v1/donation_campaigns_controller.rb @@ -60,7 +60,7 @@ class Api::V1::DonationCampaignsController < Api::BaseController return JSON.parse(res.body_with_limit) if res.code == 200 end end - rescue *Mastodon::HTTP_CONNECTION_ERRORS, Oj::ParseError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, JSON::ParserError nil end diff --git a/app/helpers/json_ld_helper.rb b/app/helpers/json_ld_helper.rb index 8ff77e3c57a..83a083469a9 100644 --- a/app/helpers/json_ld_helper.rb +++ b/app/helpers/json_ld_helper.rb @@ -314,7 +314,7 @@ module JsonLdHelper return if compare_id.present? && json['id'] != compare_id json - rescue Oj::ParseError + rescue JSON::ParserError nil end diff --git a/app/lib/admin/metrics/dimension/software_versions_dimension.rb b/app/lib/admin/metrics/dimension/software_versions_dimension.rb index 6c4de0e3ec0..3e815795841 100644 --- a/app/lib/admin/metrics/dimension/software_versions_dimension.rb +++ b/app/lib/admin/metrics/dimension/software_versions_dimension.rb @@ -88,7 +88,7 @@ class Admin::Metrics::Dimension::SoftwareVersionsDimension < Admin::Metrics::Dim value: version, human_value: version, } - rescue Terrapin::CommandNotFoundError, Terrapin::ExitStatusError, Oj::ParseError + rescue Terrapin::CommandNotFoundError, Terrapin::ExitStatusError, JSON::ParserError nil end end diff --git a/app/lib/translation_service/deepl.rb b/app/lib/translation_service/deepl.rb index 59c255a7ce7..98536fe2dec 100644 --- a/app/lib/translation_service/deepl.rb +++ b/app/lib/translation_service/deepl.rb @@ -78,7 +78,7 @@ class TranslationService::DeepL < TranslationService provider: 'DeepL.com' ) end - rescue Oj::ParseError + rescue JSON::ParserError raise UnexpectedResponseError end end diff --git a/app/lib/translation_service/libre_translate.rb b/app/lib/translation_service/libre_translate.rb index b97f3342332..ffcd4ed78cc 100644 --- a/app/lib/translation_service/libre_translate.rb +++ b/app/lib/translation_service/libre_translate.rb @@ -55,7 +55,7 @@ class TranslationService::LibreTranslate < TranslationService provider: 'LibreTranslate' ) end - rescue Oj::ParseError + rescue JSON::ParserError raise UnexpectedResponseError end end diff --git a/app/lib/video_metadata_extractor.rb b/app/lib/video_metadata_extractor.rb index adef0edb861..3a0f5063682 100644 --- a/app/lib/video_metadata_extractor.rb +++ b/app/lib/video_metadata_extractor.rb @@ -9,7 +9,7 @@ class VideoMetadataExtractor @metadata = JSON.parse(ffmpeg_command_output, symbolize_names: true) parse_metadata - rescue Terrapin::ExitStatusError, Oj::ParseError + rescue Terrapin::ExitStatusError, JSON::ParserError @invalid = true rescue Terrapin::CommandNotFoundError raise Paperclip::Errors::CommandNotFoundError, 'Could not run the `ffprobe` command. Please install ffmpeg.' # rubocop:disable I18n/RailsI18n/DecorateString -- This error is not user-facing diff --git a/app/lib/webfinger.rb b/app/lib/webfinger.rb index e887de17c75..aa5bcbe2a7b 100644 --- a/app/lib/webfinger.rb +++ b/app/lib/webfinger.rb @@ -57,7 +57,7 @@ class Webfinger def perform Response.new(@uri, body_from_webfinger) - rescue Oj::ParseError + rescue JSON::ParserError raise Webfinger::Error, "Invalid JSON in response for #{@uri}" rescue Addressable::URI::InvalidURIError raise Webfinger::Error, "Invalid URI for #{@uri}" diff --git a/app/services/activitypub/fetch_remote_actor_service.rb b/app/services/activitypub/fetch_remote_actor_service.rb index 560cf424e15..1fb3f45ce58 100644 --- a/app/services/activitypub/fetch_remote_actor_service.rb +++ b/app/services/activitypub/fetch_remote_actor_service.rb @@ -19,7 +19,7 @@ class ActivityPub::FetchRemoteActorService < BaseService else body_to_json(prefetched_body, compare_id: uri) end - rescue Oj::ParseError + rescue JSON::ParserError raise Error, "Error parsing JSON-LD document #{uri}" end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index e23f4a15bbe..fb26992bf49 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -64,7 +64,7 @@ class ActivityPub::ProcessAccountService < BaseService end @account - rescue Oj::ParseError + rescue JSON::ParserError nil end diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index d9ba5d5822c..2b5043dc664 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -38,7 +38,7 @@ class ActivityPub::ProcessCollectionService < BaseService else process_items [@json] end - rescue Oj::ParseError + rescue JSON::ParserError nil end diff --git a/app/services/software_update_check_service.rb b/app/services/software_update_check_service.rb index e3bc1129642..aa2eadd94c8 100644 --- a/app/services/software_update_check_service.rb +++ b/app/services/software_update_check_service.rb @@ -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| return JSON.parse(res.body_with_limit) if res.code == 200 end - rescue *Mastodon::HTTP_CONNECTION_ERRORS, Oj::ParseError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, JSON::ParserError nil end diff --git a/spec/helpers/json_ld_helper_spec.rb b/spec/helpers/json_ld_helper_spec.rb index f216588d978..e26e9cd6378 100644 --- a/spec/helpers/json_ld_helper_spec.rb +++ b/spec/helpers/json_ld_helper_spec.rb @@ -112,6 +112,11 @@ RSpec.describe JsonLdHelper do expect(fetch_resource_without_id_validation('https://host.test/')).to be_nil end + it 'returns nil if the body is not parsable' do + stub_request(:get, 'https://host.test/').to_return(status: 200, body: 'XXX', headers: { 'Content-Type': 'application/activity+json' }) + expect(fetch_resource_without_id_validation('https://host.test/')).to be_nil + end + it 'returns hash' do stub_request(:get, 'https://host.test/').to_return(status: 200, body: '{}', headers: { 'Content-Type': 'application/activity+json' }) expect(fetch_resource_without_id_validation('https://host.test/')).to eq({}) diff --git a/spec/lib/translation_service/deepl_spec.rb b/spec/lib/translation_service/deepl_spec.rb index 4797a3dc638..a6a0ad15a29 100644 --- a/spec/lib/translation_service/deepl_spec.rb +++ b/spec/lib/translation_service/deepl_spec.rb @@ -19,6 +19,19 @@ RSpec.describe TranslationService::DeepL do end describe '#translate' do + context 'with invalid body response' do + before do + stub_request(:post, 'https://api.deepl.com/v2/translate') + .with(body: 'text=Hasta+la+vista&source_lang=ES&target_lang=en&tag_handling=html') + .to_return(body: 'XXX') + end + + it 'handles error and re-raises' do + expect { service.translate(['Hasta la vista'], 'es', 'en') } + .to raise_error(TranslationService::UnexpectedResponseError) + end + end + it 'returns translation with specified source language' do stub_request(:post, 'https://api.deepl.com/v2/translate') .with(body: 'text=Hasta+la+vista&source_lang=ES&target_lang=en&tag_handling=html') diff --git a/spec/lib/translation_service/libre_translate_spec.rb b/spec/lib/translation_service/libre_translate_spec.rb index 90966a8ebf6..4df2a2076cb 100644 --- a/spec/lib/translation_service/libre_translate_spec.rb +++ b/spec/lib/translation_service/libre_translate_spec.rb @@ -29,6 +29,19 @@ RSpec.describe TranslationService::LibreTranslate do end describe '#translate' do + context 'with invalid body response' do + before do + stub_request(:post, 'https://libretranslate.example.com/translate') + .with(body: '{"q":["Hasta la vista"],"source":"es","target":"en","format":"html","api_key":"my-api-key"}') + .to_return(body: 'XXX') + end + + it 'handles error and re-raises' do + expect { service.translate(['Hasta la vista'], 'es', 'en') } + .to raise_error(TranslationService::UnexpectedResponseError) + end + end + it 'returns translation with specified source language' do stub_request(:post, 'https://libretranslate.example.com/translate') .with(body: '{"q":["Hasta la vista"],"source":"es","target":"en","format":"html","api_key":"my-api-key"}') diff --git a/spec/lib/webfinger_spec.rb b/spec/lib/webfinger_spec.rb index 7f2251b858f..68ce841a539 100644 --- a/spec/lib/webfinger_spec.rb +++ b/spec/lib/webfinger_spec.rb @@ -37,6 +37,16 @@ RSpec.describe Webfinger do end end + context 'when response body is not parsable' do + it 'raises an error' do + stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com') + .to_return(body: 'XXX', headers: { 'Content-Type': 'application/jrd+json' }) + + expect { subject } + .to raise_error(Webfinger::Error) + end + end + context 'when webfinger fails and host meta is used' do before { stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(status: 404) } diff --git a/spec/requests/api/v1/donation_campaigns_spec.rb b/spec/requests/api/v1/donation_campaigns_spec.rb index 5df360b728b..90add508204 100644 --- a/spec/requests/api/v1/donation_campaigns_spec.rb +++ b/spec/requests/api/v1/donation_campaigns_spec.rb @@ -52,6 +52,19 @@ RSpec.describe 'Donation campaigns' do end end + context 'when the donation campaign returns bad response' do + before do + stub_request(:get, "#{api_url}?platform=web&seed=#{seed}&locale=en").to_return(body: 'Cats & Dogs', status: 200) + end + + it 'handles the error and returns http empty' do + get '/api/v1/donation_campaigns', headers: headers + + expect(response) + .to have_http_status(204) + end + end + context 'when the donation campaign API returns a campaign' do let(:campaign_json) do { diff --git a/spec/services/software_update_check_service_spec.rb b/spec/services/software_update_check_service_spec.rb index ac342dce94f..8f04b85d58b 100644 --- a/spec/services/software_update_check_service_spec.rb +++ b/spec/services/software_update_check_service_spec.rb @@ -55,6 +55,16 @@ RSpec.describe SoftwareUpdateCheckService do end end + context 'when the update server returns invalid response body' do + before do + stub_request(:get, full_update_check_url).to_return(status: 200, body: 'XXX') + end + + it 'handles the error and returns' do + expect(subject.call).to be_nil + end + end + context 'when the server returns new versions' do let(:server_json) do {