diff --git a/app/services/exercise_service/push_external.rb b/app/services/exercise_service/push_external.rb index 69c5234a2..a00009a70 100644 --- a/app/services/exercise_service/push_external.rb +++ b/app/services/exercise_service/push_external.rb @@ -17,17 +17,29 @@ def execute request.headers['Authorization'] = "Bearer #{@codeharbor_link.api_key}" request.body = body end + return nil if response.success? + return I18n.t('exercises.export_codeharbor.not_authorized') if response.status == 401 - response.success? ? nil : response.body + handle_error(message: response.body) + rescue Faraday::ServerError => e + handle_error(error: e, message: I18n.t('exercises.export_codeharbor.server_error')) rescue StandardError => e - e.message + handle_error(error: e) end end private + def handle_error(message: nil, error: nil) + Sentry.capture_exception(error) if error.present? + ERB::Util.html_escape(message || error.to_s) + end + def connection Faraday.new(url: @codeharbor_link.push_url) do |faraday| + faraday.options[:open_timeout] = 5 + faraday.options[:timeout] = 5 + faraday.adapter Faraday.default_adapter end end diff --git a/config/locales/de/exercise.yml b/config/locales/de/exercise.yml index 97b144bfb..7e9070ce4 100644 --- a/config/locales/de/exercise.yml +++ b/config/locales/de/exercise.yml @@ -102,6 +102,8 @@ de: error: Es ist ein Fehler bei der Kommunikation mit CodeHarbor aufgetreten. export_failed: 'Export ist fehlgeschlagen.
ID: %{id}
Title: %{title}

Error: %{error}' label: Zu CodeHarbor exportieren + not_authorized: Die Autorisierung mit CodeHarbor konnte nicht hergestellt werden. Ist der API-Schlüssel korrekt? + server_error: Verbindung zu CodeHarbor fehlgeschlagen. Gegenseite nicht erreichbar. successfully_exported: 'Aufgabe wurde erfolgreich exportiert.
ID: %{id}
Title: %{title}' external_users: statistics: diff --git a/config/locales/en/exercise.yml b/config/locales/en/exercise.yml index 3f9e04b15..704acc4c9 100644 --- a/config/locales/en/exercise.yml +++ b/config/locales/en/exercise.yml @@ -102,6 +102,8 @@ en: error: An error occurred while contacting CodeHarbor export_failed: 'Export has failed.
ID: %{id}
Title: %{title}

Error: %{error}' label: Export to CodeHarbor + not_authorized: Authorization with could not be established with CodeHarbor. Is the API Key correct? + server_error: Connection to CodeHarbor failed. Remote host unreachable. successfully_exported: 'Exercise has been successfully exported.
ID: %{id}
Title: %{title}' external_users: statistics: diff --git a/spec/services/exercise_service/push_external_spec.rb b/spec/services/exercise_service/push_external_spec.rb index 347d3d86e..8bc74b456 100644 --- a/spec/services/exercise_service/push_external_spec.rb +++ b/spec/services/exercise_service/push_external_spec.rb @@ -49,9 +49,40 @@ context 'when response status is 500' do let(:status) { 500 } - let(:response) { 'an error occured' } + let(:response) { 'an error occurred' } - it { is_expected.to be response } + it { is_expected.to eql response } + + context 'when response contains problematic characters' do + let(:response) { 'an occurred' } + + it { is_expected.to eql 'an <error> occurred' } + end + + context 'when faraday throws an error' do + let(:connection) { instance_double(Faraday::Connection) } + let(:error) { Faraday::ServerError } + + before do + allow(Faraday).to receive(:new).and_return(connection) + allow(connection).to receive(:post).and_raise(error) + end + + it { is_expected.to eql I18n.t('exercises.export_codeharbor.server_error') } + + context 'when another error occurs' do + let(:error) { 'another error' } + + it { is_expected.to eql 'another error' } + end + end + end + + context 'when response status is 401' do + let(:status) { 401 } + let(:response) { I18n.t('exercises.export_codeharbor.not_authorized') } + + it { is_expected.to eql response } end end