diff --git a/ee/lib/gitlab/llm/chain/agents/single_action_executor.rb b/ee/lib/gitlab/llm/chain/agents/single_action_executor.rb index e61cb3174309282a0cf1bb48fdaeac9c7fcca0b9..f52b7c26e051b35cbdf10ad4707ec1d73d94a76c 100644 --- a/ee/lib/gitlab/llm/chain/agents/single_action_executor.rb +++ b/ee/lib/gitlab/llm/chain/agents/single_action_executor.rb @@ -72,6 +72,7 @@ def execute rescue Net::ReadTimeout => error Gitlab::ErrorTracking.track_exception(error) Answer.error_answer( + error: error, context: context, content: _("I'm sorry, I couldn't respond in time. Please try again."), error_code: "A1000" @@ -79,6 +80,7 @@ def execute rescue Gitlab::Llm::AiGateway::Client::ConnectionError => error Gitlab::ErrorTracking.track_exception(error) Answer.error_answer( + error: error, context: context, error_code: "A1001" ) diff --git a/ee/lib/gitlab/llm/chain/agents/zero_shot/executor.rb b/ee/lib/gitlab/llm/chain/agents/zero_shot/executor.rb index a1a707dded293dc0fafb431eed200babbec24948..5ebcb120046f21638adca68cfdd261109ca59187 100644 --- a/ee/lib/gitlab/llm/chain/agents/zero_shot/executor.rb +++ b/ee/lib/gitlab/llm/chain/agents/zero_shot/executor.rb @@ -75,6 +75,7 @@ def execute rescue Net::ReadTimeout => error Gitlab::ErrorTracking.track_exception(error) Answer.error_answer( + error: error, context: context, content: _("I'm sorry, I couldn't respond in time. Please try again."), error_code: 'A1000' @@ -82,6 +83,7 @@ def execute rescue Gitlab::Llm::AiGateway::Client::ConnectionError => error Gitlab::ErrorTracking.track_exception(error) Answer.error_answer( + error: error, context: context, error_code: "A1001" ) diff --git a/ee/lib/gitlab/llm/chain/answer.rb b/ee/lib/gitlab/llm/chain/answer.rb index e1ee0d8694911921ba7998a71641059ef0fdcb7d..0cb224d2363d2672a16c8a4392552fe325e3255c 100644 --- a/ee/lib/gitlab/llm/chain/answer.rb +++ b/ee/lib/gitlab/llm/chain/answer.rb @@ -68,8 +68,8 @@ def self.default_final_message "Please try a more specific request or enter /clear to start a new chat.") end - def self.error_answer(context:, error_code: nil, content: default_error_answer) - logger.error(message: "Error", error: content, error_code: error_code) + def self.error_answer(context:, error_code: nil, content: default_error_answer, error: nil) + logger.error(message: error ? error.message : "Error", error: content, error_code: error_code) track_event(context, 'error_answer') new( diff --git a/ee/lib/gitlab/llm/chain/concerns/reader_tooling.rb b/ee/lib/gitlab/llm/chain/concerns/reader_tooling.rb index 79d62a34cb413a4990b0af11afdeda3fdeca50bb..98e16c0cdfa24a1772454fa444ecb7bb3f74e36c 100644 --- a/ee/lib/gitlab/llm/chain/concerns/reader_tooling.rb +++ b/ee/lib/gitlab/llm/chain/concerns/reader_tooling.rb @@ -14,8 +14,9 @@ def passed_content(_json) .resource_serialized(content_limit: provider_prompt_class::MAX_CHARACTERS * 0.6) "Please use this information about identified #{resource_name}: #{resource_serialized}" - rescue ArgumentError + rescue ArgumentError => error Answer.error_answer( + error: error, context: context, error_code: "M5000" ) diff --git a/ee/lib/gitlab/llm/chain/tools/identifier.rb b/ee/lib/gitlab/llm/chain/tools/identifier.rb index eed86cefa2c0c442611521c85591afe6b02a2d28..c3c8d4e2b48f6db2a7d204485583a2d235164653 100644 --- a/ee/lib/gitlab/llm/chain/tools/identifier.rb +++ b/ee/lib/gitlab/llm/chain/tools/identifier.rb @@ -47,6 +47,7 @@ def perform(&_block) Gitlab::ErrorTracking.track_exception(e) return Answer.error_answer( + error: e, context: context, error_code: "M4001" ) diff --git a/ee/spec/lib/gitlab/llm/chain/answer_spec.rb b/ee/spec/lib/gitlab/llm/chain/answer_spec.rb index 845c0b8e2469a4c11528bd412cc78c09bf7dc70c..94a31726dd9dd154e46207f2a742fb943721a8d9 100644 --- a/ee/spec/lib/gitlab/llm/chain/answer_spec.rb +++ b/ee/spec/lib/gitlab/llm/chain/answer_spec.rb @@ -141,9 +141,17 @@ end describe '.error_answer' do - subject(:answer) { described_class.error_answer(context: context, content: "error", error_code: error_code) } + subject(:answer) do + described_class.error_answer( + context: context, + content: "error", + error_code: error_code, + error: error + ) + end let(:error_code) { nil } + let(:error) { StandardError.new('hello world') } context 'when the answer has no error code' do it 'returns final answer with error response' do @@ -173,7 +181,35 @@ it 'logs the error code' do answer - expect(logger).to have_received(:error).with(message: "Error", error: "error", error_code: error_code) + expect(logger).to have_received(:error).with(error: "error", error_code: error_code, + message: 'hello world') + end + + context 'when error has no message' do + let(:error) { StandardError.new } + + it 'logs the error code' do + answer + + expect(logger).to have_received(:error).with(error: "error", error_code: error_code, + message: 'StandardError') + end + end + + context 'when error is not passed' do + subject(:answer) do + described_class.error_answer( + context: context, + content: "error", + error_code: error_code + ) + end + + it 'logs the error code' do + answer + + expect(logger).to have_received(:error).with(message: "Error", error: "error", error_code: error_code) + end end end