summaryrefslogtreecommitdiff
path: root/app/services/jira/requests/base.rb
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-19 09:08:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-19 09:08:42 +0000
commitb76ae638462ab0f673e5915986070518dd3f9ad3 (patch)
treebdab0533383b52873be0ec0eb4d3c66598ff8b91 /app/services/jira/requests/base.rb
parent434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff)
downloadgitlab-ce-b76ae638462ab0f673e5915986070518dd3f9ad3.tar.gz
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'app/services/jira/requests/base.rb')
-rw-r--r--app/services/jira/requests/base.rb80
1 files changed, 71 insertions, 9 deletions
diff --git a/app/services/jira/requests/base.rb b/app/services/jira/requests/base.rb
index e4e2736ca2f..56484075d08 100644
--- a/app/services/jira/requests/base.rb
+++ b/app/services/jira/requests/base.rb
@@ -6,6 +6,17 @@ module Jira
include ProjectServicesLoggable
JIRA_API_VERSION = 2
+ # Limit the size of the JSON error message we will attempt to parse, as the JSON is external input.
+ JIRA_ERROR_JSON_SIZE_LIMIT = 5_000
+
+ ERRORS = {
+ connection: [Errno::ECONNRESET, Errno::ECONNREFUSED],
+ jira_ruby: JIRA::HTTPError,
+ ssl: OpenSSL::SSL::SSLError,
+ timeout: [Timeout::Error, Errno::ETIMEDOUT],
+ uri: [URI::InvalidURIError, SocketError]
+ }.freeze
+ ALL_ERRORS = ERRORS.values.flatten.freeze
def initialize(jira_integration, params = {})
@project = jira_integration&.project
@@ -43,15 +54,66 @@ module Jira
def request
response = client.get(url)
build_service_response(response)
- rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, URI::InvalidURIError, JIRA::HTTPError, OpenSSL::SSL::SSLError => error
- error_message = "Jira request error: #{error.message}"
- log_error("Error sending message", client_url: client.options[:site],
- error: {
- exception_class: error.class.name,
- exception_message: error.message,
- exception_backtrace: Gitlab::BacktraceCleaner.clean_backtrace(error.backtrace)
- })
- ServiceResponse.error(message: error_message)
+ rescue *ALL_ERRORS => e
+ log_error('Error sending message',
+ client_url: client.options[:site],
+ error: {
+ exception_class: e.class.name,
+ exception_message: e.message,
+ exception_backtrace: Gitlab::BacktraceCleaner.clean_backtrace(e.backtrace)
+ }
+ )
+
+ ServiceResponse.error(message: error_message(e))
+ end
+
+ def error_message(error)
+ reportable_error_message(error) ||
+ s_('JiraRequest|An error occurred while requesting data from Jira. Check your Jira integration configuration and try again.')
+ end
+
+ # Returns a user-facing error message if possible, otherwise `nil`.
+ def reportable_error_message(error)
+ case error
+ when ERRORS[:jira_ruby]
+ reportable_jira_ruby_error_message(error)
+ when ERRORS[:ssl]
+ s_('JiraRequest|An SSL error occurred while connecting to Jira: %{message}. Try your request again.') % { message: error.message }
+ when *ERRORS[:uri]
+ s_('JiraRequest|The Jira API URL for connecting to Jira is not valid. Check your Jira integration API URL and try again.')
+ when *ERRORS[:timeout]
+ s_('JiraRequest|A timeout error occurred while connecting to Jira. Try your request again.')
+ when *ERRORS[:connection]
+ s_('JiraRequest|A connection error occurred while connecting to Jira. Try your request again.')
+ end
+ end
+
+ # Returns a user-facing error message for a `JIRA::HTTPError` if possible,
+ # otherwise `nil`.
+ def reportable_jira_ruby_error_message(error)
+ case error.message
+ when 'Unauthorized'
+ s_('JiraRequest|The credentials for accessing Jira are not valid. Check your Jira integration credentials and try again.')
+ when 'Forbidden'
+ s_('JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your Jira integration credentials and try again.')
+ when 'Bad Request'
+ s_('JiraRequest|An error occurred while requesting data from Jira. Check your Jira integration configuration and try again.')
+ when /errorMessages/
+ jira_ruby_json_error_message(error.message)
+ end
+ end
+
+ def jira_ruby_json_error_message(error_message)
+ return if error_message.length > JIRA_ERROR_JSON_SIZE_LIMIT
+
+ begin
+ messages = Gitlab::Json.parse(error_message)['errorMessages']&.to_sentence
+ messages = Rails::Html::FullSanitizer.new.sanitize(messages).presence
+ return unless messages
+
+ s_('JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your Jira integration configuration and try again.') % { messages: messages }
+ rescue JSON::ParserError
+ end
end
def url