newrelic_rpm 6.9.0.363 → 6.10.0.364

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +15 -0
  3. data/CHANGELOG.md +59 -5
  4. data/lib/new_relic/agent.rb +3 -2
  5. data/lib/new_relic/agent/agent.rb +2 -2
  6. data/lib/new_relic/agent/datastores/mongo.rb +1 -1
  7. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +1 -1
  8. data/lib/new_relic/agent/error_collector.rb +30 -11
  9. data/lib/new_relic/agent/error_event_aggregator.rb +4 -4
  10. data/lib/new_relic/agent/hostname.rb +7 -1
  11. data/lib/new_relic/agent/http_clients/abstract.rb +82 -0
  12. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +24 -19
  13. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +28 -13
  14. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +17 -21
  15. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +10 -11
  16. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +16 -4
  17. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +4 -6
  18. data/lib/new_relic/agent/http_clients/uri_util.rb +3 -2
  19. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +4 -5
  20. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -0
  21. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +11 -2
  22. data/lib/new_relic/agent/instrumentation/active_record.rb +4 -2
  23. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +7 -2
  24. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +8 -4
  25. data/lib/new_relic/agent/instrumentation/bunny.rb +44 -27
  26. data/lib/new_relic/agent/instrumentation/curb.rb +58 -17
  27. data/lib/new_relic/agent/instrumentation/data_mapper.rb +3 -1
  28. data/lib/new_relic/agent/instrumentation/excon/connection.rb +6 -3
  29. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +2 -1
  30. data/lib/new_relic/agent/instrumentation/http.rb +5 -2
  31. data/lib/new_relic/agent/instrumentation/httpclient.rb +4 -2
  32. data/lib/new_relic/agent/instrumentation/memcache.rb +3 -1
  33. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +6 -2
  34. data/lib/new_relic/agent/instrumentation/mongo.rb +9 -3
  35. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +13 -0
  36. data/lib/new_relic/agent/instrumentation/net.rb +5 -2
  37. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +25 -1
  38. data/lib/new_relic/agent/instrumentation/redis.rb +9 -3
  39. data/lib/new_relic/agent/instrumentation/sidekiq.rb +0 -1
  40. data/lib/new_relic/agent/instrumentation/typhoeus.rb +22 -5
  41. data/lib/new_relic/agent/logging.rb +1 -1
  42. data/lib/new_relic/agent/method_tracer_helpers.rb +1 -1
  43. data/lib/new_relic/agent/noticible_error.rb +22 -0
  44. data/lib/new_relic/agent/span_event_primitive.rb +43 -32
  45. data/lib/new_relic/agent/tracer.rb +30 -15
  46. data/lib/new_relic/agent/transaction.rb +47 -43
  47. data/lib/new_relic/agent/transaction/abstract_segment.rb +26 -0
  48. data/lib/new_relic/agent/transaction/external_request_segment.rb +25 -9
  49. data/lib/new_relic/agent/transaction_error_primitive.rb +5 -3
  50. data/lib/new_relic/cli/commands/install.rb +3 -2
  51. data/lib/new_relic/noticed_error.rb +28 -9
  52. data/lib/new_relic/rack/browser_monitoring.rb +2 -1
  53. data/lib/new_relic/version.rb +1 -1
  54. data/lib/tasks/multiverse.rb +25 -0
  55. data/lib/tasks/tests.rake +1 -1
  56. data/test/agent_helper.rb +217 -64
  57. metadata +4 -3
  58. data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
@@ -22,10 +22,12 @@ DependencyDetection.defer do
22
22
  class Curl::Easy
23
23
 
24
24
  attr_accessor :_nr_instrumented,
25
+ :_nr_failure_instrumented,
25
26
  :_nr_http_verb,
26
27
  :_nr_header_str,
27
28
  :_nr_original_on_header,
28
29
  :_nr_original_on_complete,
30
+ :_nr_original_on_failure,
29
31
  :_nr_serial
30
32
 
31
33
  # We have to hook these three methods separately, as they don't use
@@ -53,7 +55,7 @@ DependencyDetection.defer do
53
55
 
54
56
 
55
57
  # Hook the #http method to set the verb.
56
- def http_with_newrelic( verb )
58
+ def http_with_newrelic verb
57
59
  self._nr_http_verb = verb.to_s.upcase
58
60
  http_without_newrelic( verb )
59
61
  end
@@ -72,9 +74,9 @@ DependencyDetection.defer do
72
74
  alias_method :perform, :perform_with_newrelic
73
75
 
74
76
  # Record the HTTP verb for future #perform calls
75
- def method_with_newrelic(m)
76
- self._nr_http_verb = m.upcase
77
- method_without_newrelic(m)
77
+ def method_with_newrelic verb
78
+ self._nr_http_verb = verb.upcase
79
+ method_without_newrelic(verb)
78
80
  end
79
81
 
80
82
  alias_method :method_without_newrelic, :method
@@ -101,12 +103,12 @@ DependencyDetection.defer do
101
103
  include NewRelic::Agent::MethodTracer
102
104
 
103
105
  # Add CAT with callbacks if the request is serial
104
- def add_with_newrelic(curl) #THREAD_LOCAL_ACCESS
106
+ def add_with_newrelic(curl)
105
107
  if curl.respond_to?(:_nr_serial) && curl._nr_serial
106
108
  hook_pending_request(curl) if NewRelic::Agent::Tracer.tracing_enabled?
107
109
  end
108
110
 
109
- return add_without_newrelic( curl )
111
+ return add_without_newrelic curl
110
112
  end
111
113
 
112
114
  alias_method :add_without_newrelic, :add
@@ -125,9 +127,9 @@ DependencyDetection.defer do
125
127
  alias_method :perform, :perform_with_newrelic
126
128
 
127
129
 
128
- # Instrument the specified +request+ (a Curl::Easy object) and set up cross-application
129
- # tracing if it's enabled.
130
- def hook_pending_request(request) #THREAD_LOCAL_ACCESS
130
+ # Instrument the specified +request+ (a Curl::Easy object)
131
+ # and set up cross-application tracing if it's enabled.
132
+ def hook_pending_request(request)
131
133
  wrapped_request, wrapped_response = wrap_request(request)
132
134
 
133
135
  segment = NewRelic::Agent::Tracer.start_external_request_segment(
@@ -138,9 +140,11 @@ DependencyDetection.defer do
138
140
 
139
141
  segment.add_request_headers wrapped_request
140
142
 
143
+ # install all callbacks
141
144
  unless request._nr_instrumented
142
145
  install_header_callback(request, wrapped_response)
143
146
  install_completion_callback(request, wrapped_response, segment)
147
+ install_failure_callback(request, wrapped_response, segment)
144
148
  request._nr_instrumented = true
145
149
  end
146
150
  rescue => err
@@ -149,35 +153,37 @@ DependencyDetection.defer do
149
153
 
150
154
 
151
155
  # Create request and response adapter objects for the specified +request+
156
+ # NOTE: Although strange to wrap request and response at once, it works
157
+ # because curb's callback mechanism updates the instantiated wrappers
158
+ # during the life-cycle of external request
152
159
  def wrap_request(request)
153
160
  return NewRelic::Agent::HTTPClients::CurbRequest.new(request),
154
161
  NewRelic::Agent::HTTPClients::CurbResponse.new(request)
155
162
  end
156
163
 
157
-
158
- # Install a callback that will record the response headers to enable
159
- # CAT linking
160
- def install_header_callback( request, wrapped_response )
164
+ # Install a callback that will record the response headers
165
+ # to enable CAT linking
166
+ def install_header_callback(request, wrapped_response)
161
167
  original_callback = request.on_header
162
168
  request._nr_original_on_header = original_callback
163
169
  request._nr_header_str = nil
164
170
  request.on_header do |header_data|
165
171
  if original_callback
166
- original_callback.call( header_data )
172
+ original_callback.call header_data
167
173
  else
168
- wrapped_response.append_header_data( header_data )
174
+ wrapped_response.append_header_data header_data
169
175
  header_data.length
170
176
  end
171
177
  end
172
178
  end
173
179
 
174
180
  # Install a callback that will finish the trace.
175
- def install_completion_callback(request, wrapped_response, segment) #THREAD_LOCAL_ACCESS
181
+ def install_completion_callback(request, wrapped_response, segment)
176
182
  original_callback = request.on_complete
177
183
  request._nr_original_on_complete = original_callback
178
184
  request.on_complete do |finished_request|
179
185
  begin
180
- segment.read_response_headers wrapped_response
186
+ segment.process_response_headers wrapped_response
181
187
  ensure
182
188
  segment.finish if segment
183
189
  # Make sure the existing completion callback is run, and restore the
@@ -188,12 +194,47 @@ DependencyDetection.defer do
188
194
  end
189
195
  end
190
196
 
197
+ # Install a callback that will fire on failures
198
+ # NOTE: on_failure is not always called, so we're not always
199
+ # unhooking the callback. No harm/no foul in production, but
200
+ # definitely something to beware of if debugging callback issues
201
+ # _nr_failure_instrumented exists to prevent infinitely chaining
202
+ # our on_failure callback hook.
203
+ def install_failure_callback(request, wrapped_response, segment)
204
+ return if request._nr_failure_instrumented
205
+ original_callback = request.on_failure
206
+ request._nr_original_on_failure = original_callback
207
+ request.on_failure do |failed_request, error|
208
+ begin
209
+ if segment
210
+ noticible_error = NewRelic::Agent::NoticibleError.new error[0].name, error[-1]
211
+ segment.notice_error noticible_error
212
+ end
213
+ ensure
214
+ original_callback.call(failed_request, error) if original_callback
215
+ remove_failure_callback(failed_request)
216
+ end
217
+ request._nr_failure_instrumented = true
218
+ end
219
+ end
220
+
221
+ # on_failure callbacks cannot be removed in the on_complete
222
+ # callback where this method is invoked because on_complete
223
+ # fires before the on_failure!
191
224
  def remove_instrumentation_callbacks(request)
192
225
  request.on_complete(&request._nr_original_on_complete)
193
226
  request.on_header(&request._nr_original_on_header)
194
227
  request._nr_instrumented = false
195
228
  end
196
229
 
230
+ # We execute customer's on_failure callback (if any) and
231
+ # uninstall our hook here since the on_complete callback
232
+ # fires before the on_failure callback.
233
+ def remove_failure_callback(request)
234
+ request.on_failure(&request._nr_original_on_failure)
235
+ request._nr_failure_instrumented = false
236
+ end
237
+
197
238
  private
198
239
 
199
240
  def first_request_is_serial?
@@ -140,7 +140,9 @@ module NewRelic
140
140
  )
141
141
 
142
142
  begin
143
- self.send("#{method_name}_without_newrelic", *args, &blk)
143
+ NewRelic::Agent::Tracer.capture_segment_error segment do
144
+ self.send("#{method_name}_without_newrelic", *args, &blk)
145
+ end
144
146
  rescue ::DataObjects::ConnectionError => e
145
147
  raise
146
148
  rescue ::DataObjects::SQLError => e
@@ -4,8 +4,9 @@
4
4
 
5
5
  module ::Excon
6
6
  class Connection
7
+ # @connection is deprecated in newer excon versions and replaced with @data
7
8
  def newrelic_connection_params
8
- (@connection || @data)
9
+ (@data || @connection)
9
10
  end
10
11
 
11
12
  def newrelic_resolved_request_params(request_params)
@@ -27,10 +28,12 @@ module ::Excon
27
28
  response = nil
28
29
  segment.add_request_headers wrapped_request
29
30
 
30
- response = request_without_newrelic_trace(resolved_params, &block)
31
+ response = NewRelic::Agent::Tracer.capture_segment_error segment do
32
+ request_without_newrelic_trace(resolved_params, &block)
33
+ end
31
34
 
32
35
  wrapped_response = ::NewRelic::Agent::HTTPClients::ExconHTTPResponse.new(response)
33
- segment.read_response_headers wrapped_response
36
+ segment.process_response_headers wrapped_response
34
37
 
35
38
  response
36
39
  ensure
@@ -49,11 +49,12 @@ module ::Excon
49
49
  segment = datum[:connection] && datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
50
50
  if segment
51
51
  begin
52
+ segment.notice_error(datum[:error]) if datum[:error]
52
53
  datum[:connection].instance_variable_set(TRACE_DATA_IVAR, nil)
53
54
 
54
55
  if datum[:response]
55
56
  wrapped_response = ::NewRelic::Agent::HTTPClients::ExconHTTPResponse.new(datum[:response])
56
- segment.read_response_headers wrapped_response
57
+ segment.process_response_headers wrapped_response
57
58
  end
58
59
  ensure
59
60
  segment.finish if segment
@@ -29,9 +29,12 @@ DependencyDetection.defer do
29
29
 
30
30
  segment.add_request_headers wrapped_request
31
31
 
32
- response = perform_without_newrelic_trace(request, options)
32
+ response = NewRelic::Agent::Tracer.capture_segment_error segment do
33
+ perform_without_newrelic_trace(request, options)
34
+ end
35
+
33
36
  wrapped_response = ::NewRelic::Agent::HTTPClients::HTTPResponse.new response
34
- segment.read_response_headers wrapped_response
37
+ segment.process_response_headers wrapped_response
35
38
 
36
39
  response
37
40
  ensure
@@ -38,12 +38,14 @@ DependencyDetection.defer do
38
38
  response = nil
39
39
  segment.add_request_headers wrapped_request
40
40
 
41
- do_get_block_without_newrelic(req, proxy, conn, &block)
41
+ NewRelic::Agent::Tracer.capture_segment_error segment do
42
+ do_get_block_without_newrelic(req, proxy, conn, &block)
43
+ end
42
44
  response = conn.pop
43
45
  conn.push response
44
46
 
45
47
  wrapped_response = ::NewRelic::Agent::HTTPClients::HTTPClientResponse.new(response)
46
- segment.read_response_headers wrapped_response
48
+ segment.process_response_headers wrapped_response
47
49
 
48
50
  response
49
51
  ensure
@@ -46,7 +46,9 @@ module NewRelic
46
46
  operation: method_name
47
47
  )
48
48
  begin
49
- send method_name_without, *args, &block
49
+ NewRelic::Agent::Tracer.capture_segment_error segment do
50
+ send method_name_without, *args, &block
51
+ end
50
52
  ensure
51
53
  if NewRelic::Agent.config[:capture_memcache_keys]
52
54
  segment.notice_nosql_statement "#{method_name} #{args.first.inspect}"
@@ -66,7 +66,9 @@ module NewRelic
66
66
  ::NewRelic::Agent::Instrumentation::Memcache::Dalli.assign_instance_to(segment, self)
67
67
 
68
68
  begin
69
- send_multiget_without_newrelic_trace(keys)
69
+ NewRelic::Agent::Tracer.capture_segment_error segment do
70
+ send_multiget_without_newrelic_trace(keys)
71
+ end
70
72
  ensure
71
73
  if ::NewRelic::Agent.config[:capture_memcache_keys]
72
74
  segment.notice_nosql_statement "#{SEND_MULTIGET_METRIC_NAME} #{keys.inspect}"
@@ -87,7 +89,9 @@ module NewRelic
87
89
  define_method method_name do |*args, &block|
88
90
  segment = NewRelic::Agent::Tracer.start_segment name: "Ruby/Memcached/Dalli/#{method_name}"
89
91
  begin
90
- __send__ method_name_without, *args, &block
92
+ NewRelic::Agent::Tracer.capture_segment_error segment do
93
+ __send__ method_name_without, *args, &block
94
+ end
91
95
  ensure
92
96
  segment.finish if segment
93
97
  end
@@ -87,7 +87,9 @@ DependencyDetection.defer do
87
87
 
88
88
  begin
89
89
  result = NewRelic::Agent.disable_all_tracing do
90
- instrument_without_new_relic_trace(name, payload, &block)
90
+ NewRelic::Agent::Tracer.capture_segment_error segment do
91
+ instrument_without_new_relic_trace(name, payload, &block)
92
+ end
91
93
  end
92
94
 
93
95
  new_relic_notice_statement(segment, payload, name) if segment
@@ -109,7 +111,9 @@ DependencyDetection.defer do
109
111
 
110
112
  begin
111
113
  result = NewRelic::Agent.disable_all_tracing do
112
- save_without_new_relic_trace(doc, opts, &block)
114
+ NewRelic::Agent::Tracer.capture_segment_error segment do
115
+ save_without_new_relic_trace(doc, opts, &block)
116
+ end
113
117
  end
114
118
 
115
119
  new_relic_notice_statement(segment, doc, :save) if segment
@@ -131,7 +135,9 @@ DependencyDetection.defer do
131
135
 
132
136
  begin
133
137
  result = NewRelic::Agent.disable_all_tracing do
134
- ensure_index_without_new_relic_trace(spec, opts, &block)
138
+ NewRelic::Agent::Tracer.capture_segment_error segment do
139
+ ensure_index_without_new_relic_trace(spec, opts, &block)
140
+ end
135
141
  end
136
142
 
137
143
  spec = case spec
@@ -19,10 +19,23 @@ module NewRelic
19
19
  end
20
20
  end
21
21
 
22
+ ERROR_KEYS = %w{ writeErrors writeConcernError writeConcernErrors }.freeze
23
+
24
+ def error_present?(event)
25
+ if reply = event.reply
26
+ ERROR_KEYS.detect{ |key| reply[key] }
27
+ end
28
+ end
29
+
22
30
  def completed(event)
23
31
  begin
24
32
  return unless NewRelic::Agent::Tracer.tracing_enabled?
25
33
  segment = segments.delete(event.operation_id)
34
+ if segment && (error_key = error_present?(event))
35
+ # taking the last error as there can potentially be many
36
+ attributes = event.reply[error_key][-1]
37
+ segment.notice_error Mongo::Error.new("%s (%s)" % [attributes["errmsg"], attributes["code"]])
38
+ end
26
39
  segment.finish if segment
27
40
  rescue Exception => e
28
41
  log_notification_error('completed', e)
@@ -33,10 +33,13 @@ DependencyDetection.defer do
33
33
  # RUBY-1244 Disable further tracing in request to avoid double
34
34
  # counting if connection wasn't started (which calls request again).
35
35
  NewRelic::Agent.disable_all_tracing do
36
- response = request_without_newrelic_trace( request, *args, &block )
36
+ response = NewRelic::Agent::Tracer.capture_segment_error segment do
37
+ request_without_newrelic_trace(request, *args, &block)
38
+ end
37
39
  end
38
40
 
39
- segment.read_response_headers response
41
+ wrapped_response = NewRelic::Agent::HTTPClients::NetHTTPResponse.new response
42
+ segment.process_response_headers wrapped_response
40
43
  response
41
44
  ensure
42
45
  segment.finish
@@ -8,6 +8,7 @@ module NewRelic
8
8
  class NotificationsSubscriber
9
9
  def initialize
10
10
  @queue_key = ['NewRelic', self.class.name, object_id].join('-')
11
+ define_exception_method
11
12
  end
12
13
 
13
14
  def self.subscribed?
@@ -22,7 +23,7 @@ module NewRelic
22
23
 
23
24
  notifier = ActiveSupport::Notifications.notifier
24
25
 
25
- instance_variable_names.each do |name|
26
+ instance_variable_names.each do |name|
26
27
  if notifier.instance_variable_defined?(name)
27
28
  subscribers = notifier.instance_variable_get(name)
28
29
  if subscribers.is_a? Array
@@ -69,6 +70,29 @@ module NewRelic
69
70
  def state
70
71
  NewRelic::Agent::Tracer.state
71
72
  end
73
+
74
+ def define_exception_method
75
+ # we don't expect this to be called more than once, but we're being
76
+ # defensive.
77
+ return if defined?(exception_object)
78
+ return unless defined?(::ActiveSupport)
79
+ if ::ActiveSupport::VERSION::STRING < "5.0.0"
80
+ # Earlier versions of Rails did not add the exception itself to the
81
+ # payload asssessible via :exception_object, so we create a stand-in
82
+ # error object from the given class name and message.
83
+ # NOTE: no backtrace available this way, but we can notice the error
84
+ # well enough to send the necessary info the UI requires to present it.
85
+ def exception_object(payload)
86
+ exception_class, message = payload[:exception]
87
+ return nil unless exception_class
88
+ NewRelic::Agent::NoticibleError.new exception_class, message
89
+ end
90
+ else
91
+ def exception_object(payload)
92
+ payload[:exception_object]
93
+ end
94
+ end
95
+ end
72
96
  end
73
97
 
74
98
  end
@@ -71,7 +71,9 @@ DependencyDetection.defer do
71
71
  )
72
72
  begin
73
73
  segment.notice_nosql_statement(statement) if statement
74
- call_without_new_relic(*args, &block)
74
+ NewRelic::Agent::Tracer.capture_segment_error segment do
75
+ call_without_new_relic(*args, &block)
76
+ end
75
77
  ensure
76
78
  segment.finish if segment
77
79
  end
@@ -96,7 +98,9 @@ DependencyDetection.defer do
96
98
  )
97
99
  begin
98
100
  segment.notice_nosql_statement(statement)
99
- call_pipeline_without_new_relic(*args, &block)
101
+ NewRelic::Agent::Tracer.capture_segment_error segment do
102
+ call_pipeline_without_new_relic(*args, &block)
103
+ end
100
104
  ensure
101
105
  segment.finish if segment
102
106
  end
@@ -117,7 +121,9 @@ DependencyDetection.defer do
117
121
  )
118
122
 
119
123
  begin
120
- connect_without_new_relic(*args, &block)
124
+ NewRelic::Agent::Tracer.capture_segment_error segment do
125
+ connect_without_new_relic(*args, &block)
126
+ end
121
127
  ensure
122
128
  segment.finish if segment
123
129
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
2
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
3
 
@@ -60,10 +60,10 @@ module NewRelic
60
60
  module Instrumentation
61
61
  module TyphoeusTracing
62
62
 
63
- HYDRA_SEGMENT_NAME = "External/Multiple/Typhoeus::Hydra/run"
64
-
63
+ HYDRA_SEGMENT_NAME = "External/Multiple/Typhoeus::Hydra/run"
64
+ NOTICIBLE_ERROR_CLASS = "Typhoeus::Errors::TyphoeusError"
65
+
65
66
  EARLIEST_VERSION = Gem::Version.new("0.5.3")
66
-
67
67
  def self.is_supported_version?
68
68
  Gem::Version.new(Typhoeus::VERSION) >= NewRelic::Agent::Instrumentation::TyphoeusTracing::EARLIEST_VERSION
69
69
  end
@@ -72,6 +72,17 @@ module NewRelic
72
72
  request.respond_to?(:hydra) && request.hydra
73
73
  end
74
74
 
75
+ def self.response_message(response)
76
+ if response.respond_to?(:response_message)
77
+ response.response_message
78
+ elsif response.respond_to?(:return_message)
79
+ response.return_message
80
+ else
81
+ # 0.5.4 seems to have lost xxxx_message methods altogether.
82
+ "timeout"
83
+ end
84
+ end
85
+
75
86
  def self.trace(request)
76
87
  state = NewRelic::Agent::Tracer.state
77
88
  return unless state.is_execution_traced?
@@ -92,8 +103,14 @@ module NewRelic
92
103
  segment.add_request_headers wrapped_request
93
104
 
94
105
  callback = Proc.new do
95
- wrapped_response = ::NewRelic::Agent::HTTPClients::TyphoeusHTTPResponse.new(request.response)
96
- segment.read_response_headers wrapped_response
106
+ wrapped_response = HTTPClients::TyphoeusHTTPResponse.new(request.response)
107
+
108
+ segment.process_response_headers wrapped_response
109
+
110
+ if request.response.code == 0
111
+ segment.notice_error NoticibleError.new NOTICIBLE_ERROR_CLASS, response_message(request.response)
112
+ end
113
+
97
114
  segment.finish if segment
98
115
  end
99
116
  request.on_complete.unshift(callback)