Skip to content

Commit 9b3f59e

Browse files
committed
capture exceptions and close span in perform
1 parent e74539e commit 9b3f59e

File tree

6 files changed

+82
-6
lines changed

6 files changed

+82
-6
lines changed

instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/patches/dup/easy.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,15 @@ def headers=(headers)
3636
end
3737

3838
def perform
39-
otel_before_request
40-
super
39+
begin
40+
otel_before_request
41+
super
42+
rescue StandardError => e
43+
# If an exception occurs before we can call `complete`, we should add and error status and close the span
44+
@otel_span&.status = OpenTelemetry::Trace::Status.error("Request threw an exception: #{e.message}")
45+
@otel_span&.finish
46+
@otel_span = nil
47+
end
4148
end
4249

4350
def complete

instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/patches/old/easy.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,15 @@ def headers=(headers)
3333
end
3434

3535
def perform
36-
otel_before_request
37-
super
36+
begin
37+
otel_before_request
38+
super
39+
rescue StandardError => e
40+
# If an exception occurs before we can call `complete`, we should add and error status and close the span
41+
@otel_span&.status = OpenTelemetry::Trace::Status.error("Request threw an exception: #{e.message}")
42+
@otel_span&.finish
43+
@otel_span = nil
44+
end
3845
end
3946

4047
def complete

instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/patches/stable/easy.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,15 @@ def headers=(headers)
3636
end
3737

3838
def perform
39-
otel_before_request
40-
super
39+
begin
40+
otel_before_request
41+
super
42+
rescue StandardError => e
43+
# If an exception occurs before we can call `complete`, we should add and error status and close the span
44+
@otel_span&.status = OpenTelemetry::Trace::Status.error("Request threw an exception: #{e.message}")
45+
@otel_span&.finish
46+
@otel_span = nil
47+
end
4148
end
4249

4350
def complete

instrumentation/ethon/test/opentelemetry/instrumentation/ethon/dup/instrumentation_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,26 @@
8282
end
8383
end
8484
end
85+
86+
it 'when the perform fails before complete with an exception' do
87+
Ethon::Curl.stub(:easy_perform, ->(handle) { raise StandardError, "Connection failed" }) do
88+
easy.perform
89+
90+
# NOTE: check the finished spans since we expect to have closed it
91+
span = exporter.finished_spans.first
92+
_(span.name).must_equal 'HTTP'
93+
_(span.attributes['http.method']).must_equal 'N/A'
94+
_(span.attributes['http.status_code']).must_be_nil
95+
_(span.attributes['http.url']).must_equal 'http://example.com/test'
96+
_(span.attributes['http.request.method']).must_equal '_OTHER'
97+
_(span.attributes['http.response.status_code']).must_be_nil
98+
_(span.attributes['url.full']).must_equal 'http://example.com/test'
99+
_(span.status.code).must_equal(
100+
OpenTelemetry::Trace::Status::ERROR
101+
)
102+
_(easy.instance_eval { @otel_span }).must_be_nil
103+
end
104+
end
85105
end
86106

87107
describe '#complete' do

instrumentation/ethon/test/opentelemetry/instrumentation/ethon/old/instrumentation_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,23 @@
7777
end
7878
end
7979
end
80+
81+
it 'when the perform fails before complete with an exception' do
82+
Ethon::Curl.stub(:easy_perform, ->(handle) { raise StandardError, "Connection failed" }) do
83+
easy.perform
84+
85+
# NOTE: check the finished spans since we expect to have closed it
86+
span = exporter.finished_spans.first
87+
_(span.name).must_equal 'HTTP N/A'
88+
_(span.attributes['http.method']).must_equal 'N/A'
89+
_(span.attributes['http.status_code']).must_be_nil
90+
_(span.attributes['http.url']).must_equal 'http://example.com/test'
91+
_(span.status.code).must_equal(
92+
OpenTelemetry::Trace::Status::ERROR
93+
)
94+
_(easy.instance_eval { @otel_span }).must_be_nil
95+
end
96+
end
8097
end
8198

8299
describe '#complete' do
@@ -105,6 +122,7 @@ def stub_response(options)
105122

106123
it 'when response is not successful' do
107124
stub_response(response_code: 500) do
125+
binding.pry
108126
_(span.name).must_equal 'HTTP N/A'
109127
_(span.attributes['http.method']).must_equal 'N/A'
110128
_(span.attributes['http.status_code']).must_equal 500

instrumentation/ethon/test/opentelemetry/instrumentation/ethon/stable/instrumentation_test.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,23 @@
7878
end
7979
end
8080
end
81+
82+
it 'when the perform fails before complete with an exception' do
83+
Ethon::Curl.stub(:easy_perform, ->(handle) { raise StandardError, "Connection failed" }) do
84+
easy.perform
85+
86+
# NOTE: check the finished spans since we expect to have closed it
87+
span = exporter.finished_spans.first
88+
_(span.name).must_equal 'HTTP'
89+
_(span.attributes['http.request.method']).must_equal '_OTHER'
90+
_(span.attributes['http.response.status_code']).must_be_nil
91+
_(span.attributes['url.full']).must_equal 'http://example.com/test'
92+
_(span.status.code).must_equal(
93+
OpenTelemetry::Trace::Status::ERROR
94+
)
95+
_(easy.instance_eval { @otel_span }).must_be_nil
96+
end
97+
end
8198
end
8299

83100
describe '#complete' do

0 commit comments

Comments
 (0)