Skip to content

Rescue ActiveSupport::DeprecationException to prevent crashes - #2386

Closed
ndbroadbent wants to merge 1 commit into
Shopify:mainfrom
DocSpring:nathan/ignore_activesupport_deprecation
Closed

Rescue ActiveSupport::DeprecationException to prevent crashes#2386
ndbroadbent wants to merge 1 commit into
Shopify:mainfrom
DocSpring:nathan/ignore_activesupport_deprecation

Conversation

@ndbroadbent

@ndbroadbent ndbroadbent commented Sep 11, 2025

Copy link
Copy Markdown

Motivation

This fixes a crash I was seeing with the Dotenv gem. They use ActiveSupport::Deprecation::DeprecatedConstantProxy for their old Railtie module so it blows up if anything touches it (since we raise on deprecation warnings in our app).

Implementation

I added some begin...rescue blocks to catch any deprecation exceptions and suppress them.

Tests

I've added some tests to ensure that tapioca ignores DeprecationException for these cases. These are the only locations where it was crashing, and now tapioca dsl runs without errors.

Crash Backtrace

/Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/compilers/active_support_concern.rb:76:in 'block in Tapioca::Dsl::Compilers::ActiveSupportConcern.gather_constants': DEPRECATION WARNING: Dotenv::Railtie is deprecated! Use Dotenv::Rails instead. (called from Kernel#load at ./bin/tapioca:27) (ActiveSupport::DeprecationException)
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/compilers/active_support_concern.rb:73:in 'Array#select'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/compilers/active_support_concern.rb:73:in 'Tapioca::Dsl::Compilers::ActiveSupportConcern.gather_constants'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'UnboundMethod#bind_call'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'block in Tapioca::Dsl::Compilers::ActiveSupportConcern._on_method_added'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/compiler.rb:46:in 'Tapioca::Dsl::Compiler.processable_constants'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/pipeline.rb:127:in 'block in Tapioca::Dsl::Pipeline#gather_constants'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/pipeline.rb:126:in 'Array#each'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/pipeline.rb:126:in 'Tapioca::Dsl::Pipeline#gather_constants'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'UnboundMethod#bind_call'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'block in Tapioca::Dsl::Pipeline#_on_method_added'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/dsl/pipeline.rb:53:in 'Tapioca::Dsl::Pipeline#run'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'UnboundMethod#bind_call'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'block in Tapioca::Dsl::Pipeline#_on_method_added'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/commands/abstract_dsl.rb:65:in 'Tapioca::Commands::AbstractDsl#generate_dsl_rbi_files'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/commands/dsl_generate.rb:17:in 'Tapioca::Commands::DslGenerate#execute'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'UnboundMethod#bind_call'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'block in Tapioca::Commands::DslGenerate#_on_method_added'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/commands/command.rb:28:in 'block in Tapioca::Commands::Command#run'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca.rb:20:in 'block in Tapioca.silence_warnings'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/site_ruby/3.4.0/rubygems/user_interaction.rb:46:in 'Gem::DefaultUserInteraction.use_ui'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca.rb:19:in 'Tapioca.silence_warnings'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/commands/command.rb:27:in 'Tapioca::Commands::Command#run'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'UnboundMethod#bind_call'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/sorbet-runtime-0.6.12466/lib/types/private/methods/_methods.rb:279:in 'block in Tapioca::Commands::Command#_on_method_added'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/lib/tapioca/cli.rb:179:in 'Tapioca::Cli#dsl'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/thor-1.4.0/lib/thor/command.rb:28:in 'Thor::Command#run'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/thor-1.4.0/lib/thor/invocation.rb:127:in 'Thor::Invocation#invoke_command'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/thor-1.4.0/lib/thor.rb:538:in 'Thor.dispatch'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/thor-1.4.0/lib/thor/base.rb:584:in 'Thor::Base::ClassMethods#start'
	from /Users/ndbroadbent/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/tapioca-0.17.7/exe/tapioca:31:in '<top (required)>'
	from ./bin/tapioca:27:in 'Kernel#load'
	from ./bin/tapioca:27:in '<main>'

@ndbroadbent
ndbroadbent requested a review from a team as a code owner September 11, 2025 03:54
@ndbroadbent

Copy link
Copy Markdown
Author

I have signed the CLA!

!mod.singleton_class? &&
ActiveSupport::Concern > mod.singleton_class &&
has_dependencies?(mod)
rescue ActiveSupport::DeprecationException

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure if this is the right way to go 🙁 . Also, this could theoretically happen with any DSL compiler, and we'd need rescue calls in each one.

I took a look at alternatives, and unfortunately you can't use the --skip-constant option because those constants are still loaded during the gathering phase. I think the only other viable solutions are:

  1. Not loading the deprecated constant in the first place from your application. If it's not in ObjectSpace after app boot, it won't be accessed by Tapioca's DSL compilers.
  2. Don't raise deprecation warnings while Tapioca is running. You could detect this by looking at Kernel#caller or through an ENV variable set while running Tapioca.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree, this isn't the right fix.

We already have handling for DeprecatedConstantProxy classes in the gem pipeline, we could implement something similar in the DSL pipeline as well: https://github.com/Shopify/tapioca/blob/main/lib/tapioca/gem/pipeline.rb#L512-L524

@egiurleo egiurleo assigned egiurleo and unassigned egiurleo Sep 12, 2025
@Morriar

Morriar commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

It looks like this is not going in the right direction. I'll close for now.

@Morriar Morriar closed this Jan 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants