Improve routes source location detection

Followup: https://github.com/rails/rails/pull/50923

Instead of stopping on the first frame that isn't in
Action Dispatch, we should return the first frame that
isn't filtered by the backtrace cleaner.
This commit is contained in:
Jean Boussier 2024-02-05 09:37:27 +01:00
parent 0add5dba83
commit bbc7ec49fb
4 changed files with 48 additions and 14 deletions

@ -66,7 +66,6 @@ class Railtie < Rails::Railtie # :nodoc:
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
ActionDispatch::Routing::Mapper.backtrace_cleaner = Rails.backtrace_cleaner
ActionDispatch.test_app = app
end

@ -10,10 +10,19 @@
module ActionDispatch
module Routing
class Mapper
class BacktraceCleaner < ActiveSupport::BacktraceCleaner # :nodoc:
def initialize
super
remove_silencers!
add_core_silencer
add_stdlib_silencer
end
end
URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port]
cattr_accessor :route_source_locations, instance_accessor: false, default: false
cattr_accessor :backtrace_cleaner, instance_accessor: false, default: ActiveSupport::BacktraceCleaner.new
cattr_accessor :backtrace_cleaner, instance_accessor: false, default: BacktraceCleaner.new
class Constraints < Routing::Endpoint # :nodoc:
attr_reader :app, :constraints
@ -366,11 +375,10 @@ def route_source_location
Thread.each_caller_location do |location|
next if location.path.start_with?(action_dispatch_dir)
if cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
return "#{cleaned_path}:#{location.lineno}"
else
return nil
end
cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
next if cleaned_path.nil?
return "#{cleaned_path}:#{location.lineno}"
end
nil
end
@ -382,11 +390,10 @@ def route_source_location
caller_locations.each do |location|
next if location.path.start_with?(action_dispatch_dir)
if cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
return "#{cleaned_path}:#{location.lineno}"
else
return nil
end
cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
next if cleaned_path.nil?
return "#{cleaned_path}:#{location.lineno}"
end
nil
end

@ -10,9 +10,11 @@ class BacktraceCleaner < ActiveSupport::BacktraceCleaner # :nodoc:
def initialize
super
@root = "#{Rails.root}/"
add_filter do |line|
line.start_with?(@root) ? line.from(@root.size) : line
# We may be called before Rails.root is assigned.
# When that happens we fallback to not truncating.
@root ||= Rails.root && "#{Rails.root}/"
@root && line.start_with?(@root) ? line.from(@root.size) : line
end
add_filter do |line|
if RENDER_TEMPLATE_PATTERN.match?(line)

@ -242,127 +242,153 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
run_routes_command([ "--expanded" ])
end
rails_gem_root = File.expand_path("../../../../", __FILE__)
assert_equal <<~MESSAGE, output
--[ Route 1 ]--------------
Prefix | cart
Verb | GET
URI | /cart(.:format)
Controller#Action | cart#show
Source Location | #{app_path}/config/routes.rb:2
--[ Route 2 ]--------------
Prefix | rails_postmark_inbound_emails
Verb | POST
URI | /rails/action_mailbox/postmark/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/postmark/inbound_emails#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:5
--[ Route 3 ]--------------
Prefix | rails_relay_inbound_emails
Verb | POST
URI | /rails/action_mailbox/relay/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/relay/inbound_emails#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:6
--[ Route 4 ]--------------
Prefix | rails_sendgrid_inbound_emails
Verb | POST
URI | /rails/action_mailbox/sendgrid/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/sendgrid/inbound_emails#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:7
--[ Route 5 ]--------------
Prefix | rails_mandrill_inbound_health_check
Verb | GET
URI | /rails/action_mailbox/mandrill/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/mandrill/inbound_emails#health_check
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:10
--[ Route 6 ]--------------
Prefix | rails_mandrill_inbound_emails
Verb | POST
URI | /rails/action_mailbox/mandrill/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/mandrill/inbound_emails#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:11
--[ Route 7 ]--------------
Prefix | rails_mailgun_inbound_emails
Verb | POST
URI | /rails/action_mailbox/mailgun/inbound_emails/mime(.:format)
Controller#Action | action_mailbox/ingresses/mailgun/inbound_emails#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:14
--[ Route 8 ]--------------
Prefix | rails_conductor_inbound_emails
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#index
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:19
--[ Route 9 ]--------------
Prefix |#{" "}
Verb | POST
URI | /rails/conductor/action_mailbox/inbound_emails(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:19
--[ Route 10 ]-------------
Prefix | new_rails_conductor_inbound_email
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails/new(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#new
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:19
--[ Route 11 ]-------------
Prefix | rails_conductor_inbound_email
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#show
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:19
--[ Route 12 ]-------------
Prefix | new_rails_conductor_inbound_email_source
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails/sources/new(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails/sources#new
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:20
--[ Route 13 ]-------------
Prefix | rails_conductor_inbound_email_sources
Verb | POST
URI | /rails/conductor/action_mailbox/inbound_emails/sources(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails/sources#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:21
--[ Route 14 ]-------------
Prefix | rails_conductor_inbound_email_reroute
Verb | POST
URI | /rails/conductor/action_mailbox/:inbound_email_id/reroute(.:format)
Controller#Action | rails/conductor/action_mailbox/reroutes#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:23
--[ Route 15 ]-------------
Prefix | rails_conductor_inbound_email_incinerate
Verb | POST
URI | /rails/conductor/action_mailbox/:inbound_email_id/incinerate(.:format)
Controller#Action | rails/conductor/action_mailbox/incinerates#create
Source Location | #{rails_gem_root}/actionmailbox/config/routes.rb:24
--[ Route 16 ]-------------
Prefix | rails_service_blob
Verb | GET
URI | /rails/active_storage/blobs/redirect/:signed_id/*filename(.:format)
Controller#Action | active_storage/blobs/redirect#show
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:5
--[ Route 17 ]-------------
Prefix | rails_service_blob_proxy
Verb | GET
URI | /rails/active_storage/blobs/proxy/:signed_id/*filename(.:format)
Controller#Action | active_storage/blobs/proxy#show
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:6
--[ Route 18 ]-------------
Prefix |#{" "}
Verb | GET
URI | /rails/active_storage/blobs/:signed_id/*filename(.:format)
Controller#Action | active_storage/blobs/redirect#show
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:7
--[ Route 19 ]-------------
Prefix | rails_blob_representation
Verb | GET
URI | /rails/active_storage/representations/redirect/:signed_blob_id/:variation_key/*filename(.:format)
Controller#Action | active_storage/representations/redirect#show
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:9
--[ Route 20 ]-------------
Prefix | rails_blob_representation_proxy
Verb | GET
URI | /rails/active_storage/representations/proxy/:signed_blob_id/:variation_key/*filename(.:format)
Controller#Action | active_storage/representations/proxy#show
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:10
--[ Route 21 ]-------------
Prefix |#{" "}
Verb | GET
URI | /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format)
Controller#Action | active_storage/representations/redirect#show
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:11
--[ Route 22 ]-------------
Prefix | rails_disk_service
Verb | GET
URI | /rails/active_storage/disk/:encoded_key/*filename(.:format)
Controller#Action | active_storage/disk#show
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:13
--[ Route 23 ]-------------
Prefix | update_rails_disk_service
Verb | PUT
URI | /rails/active_storage/disk/:encoded_token(.:format)
Controller#Action | active_storage/disk#update
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:14
--[ Route 24 ]-------------
Prefix | rails_direct_uploads
Verb | POST
URI | /rails/active_storage/direct_uploads(.:format)
Controller#Action | active_storage/direct_uploads#create
Source Location | #{rails_gem_root}/activestorage/config/routes.rb:15
MESSAGE
end