Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Bug Fixes

- Use `ActionDispatch::ExceptionWrapper` for correct HTTP status code ([#2850](https://github.com/getsentry/sentry-ruby/pull/2850))
- Add explicit dependency on logger gem to fix Ruby 4.0 warning ([#2837](https://github.com/getsentry/sentry-ruby/pull/2837))

### Internal
Expand Down
4 changes: 4 additions & 0 deletions sentry-rails/lib/sentry/rails/capture_exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ def show_exceptions?(exception, env)
request.show_exceptions?
end
end

def status_code_for_exception(exception)
ActionDispatch::ExceptionWrapper.status_code_for_exception(exception.class.name)
end
end
end
end
59 changes: 59 additions & 0 deletions sentry-rails/spec/sentry/rails/tracing_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,63 @@
end
end

context "with report_rescued_exceptions and public error pages" do
before do
make_basic_app do |config, app|
config.traces_sample_rate = 1.0
config.rails.report_rescued_exceptions = true
config.excluded_exceptions -= ['ActionController::RoutingError']
app.config.consider_all_requests_local = false
end
end

it "records correct status code for 404 errors served by public error pages" do
get "/nonexistent_route"

expect(response).to have_http_status(:not_found)
expect(transport.events.count).to be >= 1

event = transport.events.first.to_h
expect(event.dig(:contexts, :trace, :data, "http.response.status_code")).to eq(404)
end
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to also add the test from my branch to see what happens

    it "records correct status when Rails rescues exception to non-500 status" do
      get "/posts/999999"

      expect(response).to have_http_status(:not_found)
      expect(transport.events.count).to eq(1)

      transaction = transport.events.last.to_h

      expect(transaction[:type]).to eq("transaction")

      first_span = transaction[:spans][0]
      expect(first_span[:op]).to eq("view.process_action.action_controller")
      expect(first_span[:description]).to eq("PostsController#show")
      expect(first_span[:status]).to eq("not_found")
      expect(first_span[:data]["http.response.status_code"]).to eq(404)
    end


context "with public error pages for controller exceptions" do
before do
make_basic_app do |config, app|
config.traces_sample_rate = 1.0
app.config.consider_all_requests_local = false
config.trace_ignore_status_codes = [(301..303), (305..399)]

# In Rails < 6.0, ActiveRecord::RecordNotFound is not automatically mapped to :not_found
# https://github.com/rails/rails/blob/main/guides/source/configuring.md?configaction_dispatchrescue_responses
# We need to add it to the rescue_responses hash
if Rails.gem_version < Gem::Version.new("6.0.0")
ActionDispatch::ExceptionWrapper.rescue_responses['ActiveRecord::RecordNotFound'] = :not_found
end
end
end

it "records correct status when Rails rescues exception to non-500 status" do
get "/posts/999999"

expect(response).to have_http_status(:not_found)
expect(transport.events.count).to eq(1)

transaction = transport.events.last.to_h

expect(transaction[:type]).to eq("transaction")
expect(transaction.dig(:contexts, :trace, :status)).to eq("not_found")
expect(transaction.dig(:contexts, :trace, :data, "http.response.status_code")).to eq(404)

first_span = transaction[:spans][0]
expect(first_span[:op]).to eq("view.process_action.action_controller")
expect(first_span[:description]).to eq("PostsController#show")
expect(first_span[:status]).to eq("internal_error")
expect(first_span[:data]["http.response.status_code"]).to eq(500)
end
end

describe "filtering pii data" do
context "with send_default_pii = false" do
before do
Expand Down Expand Up @@ -210,6 +267,8 @@
config.traces_sample_rate = 1.0
config.sdk_logger = logger
config.rails.assets_regexp = %r{/foo/}
# Allow 404 status codes to be traced (default ignores 401-404)
config.trace_ignore_status_codes = [(301..303), (305..399)]
end
end

Expand Down
6 changes: 5 additions & 1 deletion sentry-ruby/lib/sentry/rack/capture_exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def call(env)
raise # Don't capture Sentry errors
rescue Exception => e
capture_exception(e, env)
finish_transaction(transaction, 500)
finish_transaction(transaction, status_code_for_exception(e))
raise
end

Expand Down Expand Up @@ -86,6 +86,10 @@ def finish_transaction(transaction, status_code)
def mechanism
Sentry::Mechanism.new(type: MECHANISM_TYPE, handled: false)
end

def status_code_for_exception(exception)
500
end
end
end
end
Loading