# frozen_string_literal: true require 'gitlab' module GitlabQuality module TestTooling module GitlabClient class GitlabClient RETRY_BACK_OFF_DELAY = 60 MAX_RETRY_ATTEMPTS = 3 def initialize(token:, project:, **_kwargs) @token = token @project = project @retry_backoff = 0 end def handle_gitlab_client_exceptions # rubocop:disable Metrics/AbcSize yield rescue Gitlab::Error::NotFound # This error could be raised in assert_user_permission! # If so, we want it to terminate at that point raise rescue SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::InternalServerError, Gitlab::Error::BadRequest, Gitlab::Error::ResponseError, Gitlab::Error::Parsing => e @retry_backoff += RETRY_BACK_OFF_DELAY raise if @retry_backoff > RETRY_BACK_OFF_DELAY * MAX_RETRY_ATTEMPTS warn_exception(e) warn("Sleeping for #{@retry_backoff} seconds before retrying...") sleep @retry_backoff retry rescue StandardError => e pipeline = Runtime::Env.pipeline_from_project_name channel = case pipeline when "canary" "qa-production" when "staging-canary" "qa-staging" else "qa-#{pipeline}" end error_msg = warn_exception(e) return unless Runtime::Env.ci_commit_ref_name == Runtime::Env.default_branch slack_options = { slack_webhook_url: ENV.fetch('CI_SLACK_WEBHOOK_URL', nil), channel: channel, username: "GitLab Quality Test Tooling", icon_emoji: ':ci_failing:', message: <<~MSG An unexpected error occurred while reporting test results in issues. The error occurred in job: #{Runtime::Env.ci_job_url} `#{error_msg}` MSG } puts "Posting Slack message to channel: #{channel}" GitlabQuality::TestTooling::Slack::PostToSlack.new(**slack_options).invoke! end def ignore_gitlab_client_exceptions yield rescue StandardError, SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::Error => e puts "Ignoring the following error: #{e}" end private attr_reader :project, :token def client @client ||= Gitlab.client( endpoint: Runtime::Env.gitlab_api_base, private_token: token ) end def warn_exception(error) error_msg = "#{error.class.name} #{error.message}" warn(error_msg) error_msg end end end end end