Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture Rails exception before default error page is rendered #1684

Merged
merged 3 commits into from
Oct 6, 2021

Conversation

marcotc
Copy link
Member

@marcotc marcotc commented Sep 14, 2021

Follow up to https://github.com/DataDog/dd-trace-rb/pull/552/files#diff-22e85fccca5492ebff5fee5e488aa5b4b2e4a62862dfc12af0ba990e0076b2c2R45-R52 and #1124.

This PR ensures we capture a Rails before some of the Rails' middlewares are able to swallow it.

In https://github.com/DataDog/dd-trace-rb/pull/552/files#diff-22e85fccca5492ebff5fee5e488aa5b4b2e4a62862dfc12af0ba990e0076b2c2R45-R52, we added a ddtrace middleware to catch such errors, but retrieving the error before the ActionDispatch::ShowExceptions Rails middleware runs. This works the majority of cases.

But if the user has action_dispatch.show_exceptions enabled, which is true by default, the Rails error page is rendered, like this one:

image

This page is rendered by the ActionDispatch::DebugExceptions middleware, which consumes the error from the stack. This middleware swallows the error before it gets a chance to hit ActionDispatch::ShowExceptions, and along with it our own middleware.

This PR inserts our error handling middleware before ActionDispatch::DebugExceptions, instead of ActionDispatch::ShowExceptions. This will address all Rails error page rendering cases today.

One caveat for Rails 3.0 only: ActionDispatch::DebugExceptions didn't exist at the time, so ActionDispatch::ShowExceptions stays as our hook point for Rails 3.0.

@marcotc marcotc added bug Involves a bug integrations Involves tracing integrations labels Sep 14, 2021
@marcotc marcotc requested a review from a team September 14, 2021 23:01
@marcotc marcotc self-assigned this Sep 14, 2021
@codecov-commenter
Copy link

codecov-commenter commented Sep 14, 2021

Codecov Report

Merging #1684 (0fb3d77) into master (9d86b38) will decrease coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1684      +/-   ##
==========================================
- Coverage   98.31%   98.29%   -0.02%     
==========================================
  Files         925      925              
  Lines       44564    44566       +2     
==========================================
- Hits        43812    43808       -4     
- Misses        752      758       +6     
Impacted Files Coverage Δ
spec/ddtrace/contrib/rails/support/rails3.rb 94.04% <ø> (-0.08%) ⬇️
spec/ddtrace/contrib/rails/support/rails4.rb 90.41% <ø> (-0.13%) ⬇️
spec/ddtrace/contrib/rails/support/rails5.rb 92.53% <ø> (-0.11%) ⬇️
spec/ddtrace/contrib/rails/support/rails6.rb 94.18% <ø> (-0.07%) ⬇️
lib/ddtrace/contrib/rails/patcher.rb 100.00% <100.00%> (ø)
spec/ddtrace/contrib/rails/support/base.rb 95.00% <100.00%> (+0.35%) ⬆️
spec/support/configuration_helpers.rb 100.00% <100.00%> (ø)
spec/ddtrace/contrib/rails/support/middleware.rb 33.33% <0.00%> (-66.67%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9d86b38...0fb3d77. Read the comment docs.

Copy link
Member

@ivoanjo ivoanjo left a comment

Choose a reason for hiding this comment

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

Left a few notes, but maybe the last Rails-foo check should be done by @delner since my Rails-foo is not that strong :)

lib/ddtrace/contrib/rails/patcher.rb Outdated Show resolved Hide resolved
spec/ddtrace/contrib/rails/rack_spec.rb Outdated Show resolved Hide resolved
spec/ddtrace/contrib/rails/support/rails3.rb Outdated Show resolved Hide resolved
@marcotc marcotc requested a review from delner September 15, 2021 17:19
Copy link
Contributor

@delner delner left a comment

Choose a reason for hiding this comment

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

So is this what was causing error: true? Only if the "show exceptions page" feature was enabled? Although I'm not surprised that this was indeed one such case, I still wonder if this is the only such case, or whether there was something else. I didn't think this feature was widely used on production applications where error: true has been reported before.

Do we still allow the user app to consume the error with this change? Or does it change the behavior of middleware downstream from ours?

Other than that, one minor comment that probably doesn't have any impact.

# Rails >= 3.2
app.middleware.insert_after(::ActionDispatch::DebugExceptions, Datadog::Contrib::Rails::ExceptionMiddleware)
else
# Rails < 3.2
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we still support Rails < 3.2? Thought we dropped support for this.

Copy link
Member Author

Choose a reason for hiding this comment

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

We still support it for Ruby 2.1:

declare 'bundle exec appraisal rails30-postgres rake spec:rails'

But I can see it as a good candidate for deprecation. It would simplify our code base for sure.

Copy link
Member

@ivoanjo ivoanjo Oct 6, 2021

Choose a reason for hiding this comment

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

👍 I think dropping support for Rails 3.1 even before we drop support for Ruby 2.1 makes sense, given that the 3.2 series still works for 2.1 thus I suspect the intersection of the following groups:

  • customers still on 2.1
  • customers still on Rails 3.1
  • customers that upgrade dd-trace-rb regularly

is probably nil or very close to it.

@marcotc
Copy link
Member Author

marcotc commented Oct 5, 2021

So is this what was causing error: true? Only if the "show exceptions page" feature was enabled? Although I'm not surprised that this was indeed one such case, I still wonder if this is the only such case, or whether there was something else. I didn't think this feature was widely used on production applications where error: true has been reported before.

This is a common scenario for clients during onboarding, for staging environments, and clients that don't ever care about their error page when their Rails app is behind a proxy (thus don't ever check if their error pages are fancily rendered or not).

I agree that this does not affect most well-behaved production Rails environments, and that makes sense, given this issue is only sporadically reported to us.

I don't have complete confidence that this solves every single error: true issue, but it does solve it for a few cases that match clients' steps-to-reproduce apps.

Do we still allow the user app to consume the error with this change? Or does it change the behavior of middleware downstream from ours?

Yes, no behavior change takes place in our middleware.

Copy link
Contributor

@delner delner left a comment

Choose a reason for hiding this comment

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

Okay, if this is an incremental improvement with no downstream impact on other middleware (which it doesn't sound like it does) then this is good. Thank you! 👍

@marcotc marcotc merged commit e88c7aa into master Oct 6, 2021
@marcotc marcotc deleted the fix-rails-error-middleware branch October 6, 2021 19:39
@github-actions github-actions bot added this to the 0.53.0 milestone Oct 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Involves a bug integrations Involves tracing integrations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants