Skip to content

fix(cache): QueryCacheManager.get() should fail open on cache backend errors#42252

Open
aminghadersohi wants to merge 1 commit into
apache:masterfrom
aminghadersohi:aminghadersohi/query-cache-manager-fail-open
Open

fix(cache): QueryCacheManager.get() should fail open on cache backend errors#42252
aminghadersohi wants to merge 1 commit into
apache:masterfrom
aminghadersohi:aminghadersohi/query-cache-manager-fail-open

Conversation

@aminghadersohi

Copy link
Copy Markdown
Contributor

SUMMARY

QueryCacheManager.get() reads from the configured cache backend with:

if cache_value := _cache[region].get(key):

This read is not wrapped in any error handling. If the cache backend (e.g. Redis) raises a connection, timeout, or other backend-specific error on read, the exception propagates all the way up through the chart/dashboard data API (POST /api/v1/chart/data) and surfaces as an unhandled 500, instead of gracefully falling back to querying live data — which is exactly what already happens one branch up on a normal cache miss (if not key or not _cache[region] or force_query: return query_cache).

In other words: any transient cache backend hiccup — not just a full outage — turns into hard failures for chart and dashboard rendering, even though the data can still be queried live.

This PR wraps the cache read in a try/except, logs the failure at a level appropriate for a potentially noisy/flaky backend, and falls through to the existing cache-miss path so the behavior matches a normal cache miss rather than raising.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — backend error-handling change, no UI impact.

TESTING INSTRUCTIONS

  • Added tests/unit_tests/common/test_query_cache_manager.py:
    • test_get_cache_miss — baseline: a normal cache miss returns a non-loaded QueryCacheManager.
    • test_get_cache_backend_error_fails_open — mocks the cache backend's .get() to raise a ConnectionError, and asserts QueryCacheManager.get() returns the same result as a normal cache miss instead of propagating the exception.
  • Manual repro: point CACHE_CONFIG/DATA_CACHE_CONFIG at a Redis instance, then stop/block Redis while calling POST /api/v1/chart/data for a datasource with caching enabled. Before this change: request fails with a 500. After this change: request falls back to querying live data.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

… errors

Reading from the query cache in QueryCacheManager.get() was not wrapped
in error handling. If the configured cache backend (e.g. Redis) raised
a connection or timeout error on read, the exception propagated all
the way up through the chart/dashboard data API and surfaced as an
unhandled 500, instead of falling back to querying live data the same
way a normal cache miss already does.

Wrap the cache read in a try/except, log the failure, and treat it
exactly like a cache miss so callers gracefully fall back to querying
live data.
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.22%. Comparing base (158e321) to head (ff3f648).

Files with missing lines Patch % Lines
superset/common/utils/query_cache_manager.py 50.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #42252      +/-   ##
==========================================
- Coverage   65.22%   65.22%   -0.01%     
==========================================
  Files        2768     2768              
  Lines      156280   156285       +5     
  Branches    35774    35774              
==========================================
- Hits       101933   101932       -1     
- Misses      52382    52387       +5     
- Partials     1965     1966       +1     
Flag Coverage Δ
hive 38.60% <0.00%> (-0.01%) ⬇️
mysql 57.86% <50.00%> (-0.01%) ⬇️
postgres 57.92% <50.00%> (-0.01%) ⬇️
presto 40.54% <50.00%> (-0.01%) ⬇️
python 59.32% <50.00%> (-0.01%) ⬇️
sqlite 57.52% <50.00%> (-0.01%) ⬇️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aminghadersohi
aminghadersohi marked this pull request as ready for review July 20, 2026 21:01
@dosubot dosubot Bot added the infra:caching Infra setup and configuration related to caching label Jul 20, 2026
@aminghadersohi
aminghadersohi requested a review from eschutho July 20, 2026 21:04
@bito-code-review

bito-code-review Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #438967

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: ff3f648..ff3f648
    • superset/common/utils/query_cache_manager.py
    • tests/unit_tests/common/test_query_cache_manager.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

infra:caching Infra setup and configuration related to caching size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant