Report the errors swallowed while computing a cache digest - #2712
Open
erikaxel wants to merge 1 commit into
Open
Report the errors swallowed while computing a cache digest#2712erikaxel wants to merge 1 commit into
erikaxel wants to merge 1 commit into
Conversation
erikaxel
force-pushed
the
vc-digest-report-swallowed-errors
branch
from
September 3, 2026 11:55
0c7ba27 to
3f3f1c3
Compare
Every rescue in the digest machinery returns a neutral value, so a misconfiguration, an autoload failure, or a raising `inherited` hook degrades to "no component dependencies" and the application serves stale HTML with nothing reported anywhere. - Route the four swallow sites through CacheDigest.handle_error - Log at `warn` through ActiveSupport's logger, preserving the production guarantee that a stale fragment beats a failed render - Raise instead in local environments, configurable with config.view_component.raise_on_cache_digest_errors
erikaxel
force-pushed
the
vc-digest-report-swallowed-errors
branch
from
September 3, 2026 11:57
3f3f1c3 to
1c1c201
Compare
This was referenced Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every rescue in the digest machinery returns a neutral value and says nothing:
CacheDigest::Resolver#find_templates→[]CacheDigest.constantize_component→nilCacheDigest.partial_paths_in→[]DependencyTracking#find_dependencies→ falls back tosuperThe rationale in the source is right — a broken digest is preferable to a broken render, and that shouldn't change for production. But it means a misconfiguration, a raising
inheritedhook, or a failed autoload is completely invisible: the digest quietly degrades to "no component dependencies",<% cache %>blocks stop being invalidated, and the application serves stale HTML.That failure mode is indistinguishable from a component that was simply never cached, which is the problem while adopting the feature. Evaluating it, we spent a while unable to tell whether we were looking at a bug, a misconfiguration, or intended behaviour, because nothing anywhere reported a problem.
Fix
All four sites now go through
CacheDigest.handle_error, which either logs the exception atwarnthrough ActiveSupport's logger:or re-raises it, controlled by a new option:
It defaults to
Rails.env.local?: raise in development and test, where a silently untracked component is a bug you want to see, and swallow-and-log in production, where the existing guarantee holds. Applications that would rather keep the current behaviour everywhere set it tofalse.Nothing about what is swallowed changed — only whether anyone finds out. The neutral return values, and the comments explaining why each one is the right degradation, are unchanged.
If you'd rather this shipped as logging only, flipping the default to
falseis a one-line change inViewComponent::Configand I'm happy to make it.Tests
The four swallow sites already had tests. Each now also asserts the logged message, and each gained a counterpart asserting the exception propagates when
raise_on_cache_digest_errorsis on:test_partial_path_extraction_swallows_parser_errors/..._raises_parser_errors_locallytest_resolver_returns_no_template_when_synthesis_fails/test_resolver_raises_when_synthesis_fails_locallytest_dependency_tracking_falls_back_when_scanning_fails/..._raises_when_scanning_fails_locallytest_constantizing_swallows_unexpected_errors/test_constantizing_raises_unexpected_errors_locallyPlus
test_digest_errors_are_swallowed_without_a_loggerfor the no-Rails-logger case, and the new default inConfigTest.bundle exec rake test,engine_test,specandeager_load_checkpass on Rails 8.1, and the caching and config suites pass on 7.1, 7.2 and 8.0. The only failures seen anywhere were pre-existing and unrelated: the allocation-count matrix inRenderingAllocationsTesthas no entry for Rails 7.1 on Ruby 3.4.Notes
Docs: a "When a digest can't be computed" section in the caching guide, and the config option in
docs/api.md.This is part of a small set of digest issues found while evaluating
ExperimentallyCacheable; the other is #2709. They're independent and can be merged in either order.