RedisCacheStoreテストで抑制されたRedisClientエラーを再スロー
RedisCacheStoreTests で発生した接続タイムアウトが nil として表面化し、原因特定が困難だった問題を、抑制された RedisClient エラーを再スローする形で可視化する変更です。テスト全体でエラーハンドリングを統一することで、失敗原因が直接出力され診断コストが下がります。
背景
このセクションでは、変更前のテスト失敗が診断情報を欠いた状態で報告されていたことを示します。テスト FailureRaisingFromMaxClientsReachedErrorTest#test_fetch_with_block_read_failure_raises がタイムアウトにより nil を返し、出力は "Expected nil to be truthy" だけで原因が不明でした。結果として、インフラ側の Redis 接続問題がテストコード上で埋もれていたため、Debug ビルドでの再現が難しかった点が課題でした。
技術的な変更
lookup_store メソッドにデフォルトの error_handler を追加し、抑制された例外をそのまま再スローするようにしました。具体的には、activesupport/test/cache/stores/redis_cache_store_test.rb の lookup_store 定義が次のように変更されます。
-ActiveSupport::Cache.lookup_store(:redis_cache_store, { url: REDIS_URL, timeout: 0.1, namespace: @namespace, pool: false }.merge(options))
+ActiveSupport::Cache.lookup_store(
+ :redis_cache_store,
+ { url: REDIS_URL, timeout: 0.1, namespace: @namespace, pool: false,
+ error_handler: ->(method:, returning:, exception:) { raise exception } }
+ .merge(options)
+)
この変更により、failsafe が内部で捕捉した RedisClient の CannotConnectError や ReadTimeoutError がテスト実行時にそのまま例外として伝播します。また、同ファイル内で重複して定義されていた内部クラスの lookup_store オーバーライドを削除し、統一されたデフォルト実装に依存させています。
設計判断
エラーハンドリングを StoreTest#lookup_store のデフォルト引数に組み込んだ設計は、テスト全体で一貫した振る舞いを保証します。変更は RedisCacheStoreTests のみを対象とし、FailureSafety 系テストはエラー抑制が期待されるため影響を受けません。そのため、既存の成功ケースはそのまま通過し、失敗ケースだけが詳細エラーを出力するというトレードオフが実現されています。
まとめ
抑制された RedisClient エラーを再スローすることで、テスト失敗時に根本原因が明示されデバッグが容易になりました。変更は lookup_store のデフォルト引数として error_handler を追加するだけで、既存コードへの侵入度が低く、テスト全体の可観測性が向上しています。