Skip to content

Commit

Permalink
Merge pull request #1489 from DataDog/fix/rails_controller_error_dete…
Browse files Browse the repository at this point in the history
…ction

Fix ActionPack instrumentation #starts_with? error
  • Loading branch information
delner authored Apr 29, 2021
2 parents 6ecfa4e + 8a35b6e commit 00c9501
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ RSpec/LeadingSubject:
RSpec/ImplicitSubject:
Enabled: false

# Enforces empty line after hook declaration.
RSpec/EmptyLineAfterHook:
Enabled: false

# Enforces empty line after subject declaration.
RSpec/EmptyLineAfterSubject:
Enabled: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def finish_processing(payload)
# [christian] in some cases :status is not defined,
# rather than firing an error, simply acknowledge we don't know it.
status = payload.fetch(:status, '?').to_s
span.status = 1 if status.starts_with?('5')
span.status = 1 if status.start_with?('5')
elsif Utils.exception_is_error?(exception)
span.set_error(exception)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/ddtrace/contrib/action_pack/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def self.exception_is_error?(exception)
# You can add custom errors via `config.action_dispatch.rescue_responses`
status = ::ActionDispatch::ExceptionWrapper.status_code_for_exception(exception.class.name)
# Only 5XX exceptions are actually errors (e.g. don't flag 404s)
status.to_s.starts_with?('5')
status.to_s.start_with?('5')
else
true
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require 'ddtrace/contrib/support/spec_helper'

require 'action_controller'
require 'ddtrace'

# TODO: We plan on rewriting much of this instrumentation to bring it up to
# present day patterns/conventions. For now, just test a few known cases.
RSpec.describe Datadog::Contrib::ActionPack::ActionController::Instrumentation do
describe '::finish_processing' do
subject(:finish_processing) { described_class.finish_processing(payload) }

context 'given a payload that been started' do
before { described_class.start_processing(payload) }
after { span.finish }

let(:action_dispatch_exception) { nil }
let(:action_name) { 'index' }
let(:controller_class) { stub_const('TestController', Class.new(ActionController::Base)) }
let(:env) { { 'rack.url_scheme' => 'http' } }
let(:payload) do
{
controller: controller_class,
action: action_name,
env: env,
headers: {
# The exception this controller was given in the request,
# which is typical if the controller is configured to handle exceptions.
request_exception: action_dispatch_exception
},
tracing_context: {}
}
end

let(:span) { payload[:tracing_context][:dd_request_span] }

context 'with a 200 OK response' do
before do
expect(Datadog.logger).to_not receive(:error)
finish_processing
end

describe 'the Datadog span' do
it do
expect(span).to_not have_error
end
end
end

context 'with a 500 Server Error response' do
let(:error) do
begin
raise 'Test error'
rescue StandardError => e
e
end
end

let(:payload) do
super().merge(
exception: [error.class.name, error.message],
exception_object: error
)
end

before do
expect(Datadog.logger).to_not receive(:error)
finish_processing
end

describe 'the Datadog span' do
it do
expect(span).to have_error
end
end
end
end
end
end

0 comments on commit 00c9501

Please sign in to comment.