Skip to content

fix: serve GitHub routes when Redis is disabled (500 on every repo page) - #61

Merged
herin7 merged 1 commit into
mainfrom
fix/redis-optional-cache
Sep 8, 2026
Merged

herin7 merged 1 commit into
mainfrom
fix/redis-optional-cache

Conversation

@herin7

@herin7 herin7 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Fixes the Failed to fetch repository data. Server responded with status 500. error on every repository page.

Root cause

GET /api/github/:username/:reponamefetchRepoDetails starts with an unguarded await redisClient.get(cacheKey). RediaClient.js created and connected a Redis client unconditionally, so with Redis disabled that call rejected, landed in the controller's catch, and hit:

const status = error.response?.status || 500;

A Redis error has no .response, so every cached route reported 500 — the cache being unavailable was reported as the upstream failing.

This affects 26 call sites across api/githubApi.js, Controllers/GithubController.js and Controllers/InsightController.js — repo details, README, file tree, issues, commits, contributors, hotspots, deployments and dependency health. StatsController was the only file that had been guarded, which is why /api/stats/user-count kept working and masked how broad this was.

Fix

Fixed in the client, not at 26 call sites:

  • Without REDIS_URL, export a no-op client whose get returns null. Callers simply miss the cache and fall through to the live GitHub request.
  • On the live client, wrap get/set so a dropped connection also degrades to a miss instead of throwing. Redis credits expiring mid-flight previously produced the same 500s.
  • Drop StatsController's bespoke ?.isReady guards, now redundant.

Behaviour with Redis present is unchanged.

Verification

  • node --test server/util/RediaClient.test.js passes — asserts the disabled client reports isReady: false, returns null from get, and accepts set without throwing.
  • Deployed to the AWS host and confirmed on a live route.

🤖 Generated with Claude Code

Every cached route returned HTTP 500 with Redis unavailable. RediaClient
created and connected a client unconditionally, so the 26 unguarded
`await redisClient.get(key)` calls across githubApi, GithubController and
InsightController threw into their catch blocks, where a non-HTTP error
fell through `error.response?.status || 500`.

Fix it in the client rather than at 26 call sites: without REDIS_URL export
a no-op that misses the cache, and wrap get/set on the live client so a
dropped connection degrades to a miss too. StatsController's bespoke
`?.isReady` guards are no longer needed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 8, 2026 19:14
@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
gitforme-jbsp Ready Ready Preview Sep 8, 2026 7:14pm UTC

@herin7
herin7 merged commit 712b213 into main Sep 8, 2026
4 checks passed
@herin7
herin7 deleted the fix/redis-optional-cache branch September 8, 2026 19:17

Copilot AI left a comment

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.

🟢 Approval recommended

The core fix is centralized and low-risk, and the remaining feedback is minor (logging clarity and test state isolation).

Pull request overview

This PR fixes GitHub API route failures when Redis is disabled/unavailable by making the Redis client degrade to cache misses instead of throwing, preventing non-HTTP Redis errors from being surfaced as HTTP 500s across repository pages.

Changes:

  • Export a disabled/no-op Redis client when REDIS_URL is not set so await redisClient.get(...) safely returns null.
  • Wrap get/set on the live Redis client to tolerate dropped connections by treating failures as cache misses.
  • Simplify StatsController to always call redisClient.get/set (guards now handled centrally) and add a regression test for the disabled-client behavior.
File summaries
File Description
server/util/RediaClient.js Adds disabled-client fallback and guards live client operations to avoid throwing when Redis is unavailable.
server/Controllers/StatsController.js Removes controller-level Redis readiness checks and relies on the centralized client behavior.
server/util/RediaClient.test.js Adds a node:test regression test to validate “Redis disabled” degrades to cache misses.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +10 to +19
test('without REDIS_URL the client degrades to a cache miss', async () => {
delete process.env.REDIS_URL;
delete require.cache[require.resolve('./RediaClient')];
const redisClient = require('./RediaClient');

assert.strictEqual(redisClient.isReady, false);
assert.strictEqual(await redisClient.get('repo:herin7:gitforme'), null);
await redisClient.set('repo:herin7:gitforme', '{}', { EX: 3600 });
redisClient.on('error', () => {});
});
Comment on lines +33 to +37
try {
await client.connect();
} catch (error) {
console.error('Redis connection unavailable; continuing with JWT fallback.');
}
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.

2 participants