Skip to content

Commit 6265af3

Browse files
committed
Rescue instrumentation failures
This wouldn't be typically needed on minimally invasive approaches of prepending instrumentation around other frameworks, but since we're adding some code to insert attributes, it's probably safer to ensure instrumentation bugs wouldn't crash the user's LLM calls.
1 parent e22d9a9 commit 6265af3

2 files changed

Lines changed: 93 additions & 0 deletions

File tree

lib/opentelemetry/instrumentation/ruby_llm/patches/chat.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ def ask(message, &block)
3535
raise
3636
end
3737
end
38+
rescue StandardError => e
39+
OpenTelemetry.handle_error(exception: e)
40+
super
3841
end
3942

4043
def execute_tool(tool_call)
@@ -51,6 +54,9 @@ def execute_tool(tool_call)
5154
span.set_attribute("gen_ai.tool.call.result", result_str[0..500])
5255
result
5356
end
57+
rescue StandardError => e
58+
OpenTelemetry.handle_error(exception: e)
59+
super
5460
end
5561

5662
private

test/instrumentation_test.rb

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,31 @@ def test_records_error_on_api_failure
6767
assert_equal OpenTelemetry::Trace::Status::ERROR, span.status.code
6868
end
6969

70+
def test_ask_still_works_when_instrumentation_fails
71+
stub_request(:post, "https://api.openai.com/v1/chat/completions")
72+
.to_return(
73+
status: 200,
74+
headers: { "Content-Type" => "application/json" },
75+
body: {
76+
id: "chatcmpl-123",
77+
object: "chat.completion",
78+
model: "gpt-4o-mini",
79+
choices: [{
80+
index: 0,
81+
message: { role: "assistant", content: "Hello!" },
82+
finish_reason: "stop"
83+
}],
84+
usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
85+
}.to_json
86+
)
87+
88+
chat = RubyLLM.chat(model: "gpt-4o-mini")
89+
chat.define_singleton_method(:tracer) { raise StandardError, "instrumentation bug" }
90+
91+
response = chat.ask("Hi")
92+
assert_equal "Hello!", response.content
93+
end
94+
7095
def test_creates_span_for_tool_call
7196
calculator = Class.new(RubyLLM::Tool) do
7297
def self.name = "calculator"
@@ -141,4 +166,66 @@ def execute(expression:)
141166
assert_equal "call_abc123", tool_span.attributes["gen_ai.tool.call.id"]
142167
assert_equal "function", tool_span.attributes["gen_ai.tool.type"]
143168
end
169+
170+
def test_execute_tool_still_works_when_instrumentation_fails
171+
calculator = Class.new(RubyLLM::Tool) do
172+
def self.name = "calculator"
173+
description "Performs math"
174+
param :expression, type: "string", desc: "Math expression"
175+
176+
def execute(expression:)
177+
eval(expression).to_s
178+
end
179+
end
180+
181+
stub_request(:post, "https://api.openai.com/v1/chat/completions")
182+
.to_return(
183+
{
184+
status: 200,
185+
headers: { "Content-Type" => "application/json" },
186+
body: {
187+
id: "chatcmpl-123",
188+
object: "chat.completion",
189+
model: "gpt-4o-mini",
190+
choices: [{
191+
index: 0,
192+
message: {
193+
role: "assistant",
194+
content: nil,
195+
tool_calls: [{
196+
id: "call_abc123",
197+
type: "function",
198+
function: { name: "calculator", arguments: '{"expression":"2+2"}' }
199+
}]
200+
},
201+
finish_reason: "tool_calls"
202+
}],
203+
usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
204+
}.to_json
205+
},
206+
{
207+
status: 200,
208+
headers: { "Content-Type" => "application/json" },
209+
body: {
210+
id: "chatcmpl-456",
211+
object: "chat.completion",
212+
model: "gpt-4o-mini",
213+
choices: [{
214+
index: 0,
215+
message: { role: "assistant", content: "The answer is 4" },
216+
finish_reason: "stop"
217+
}],
218+
usage: { prompt_tokens: 20, completion_tokens: 5, total_tokens: 25 }
219+
}.to_json
220+
}
221+
)
222+
223+
chat = RubyLLM.chat(model: "gpt-4o-mini")
224+
chat.with_tool(calculator)
225+
226+
chat.define_singleton_method(:tracer) { raise StandardError, "instrumentation bug" }
227+
228+
response = chat.ask("What is 2+2?")
229+
assert_equal "The answer is 4", response.content
230+
end
144231
end

0 commit comments

Comments
 (0)