Skip to content

Commit efdeb78

Browse files
committed
fixed the Railway deployment failing
1 parent fbc3857 commit efdeb78

3 files changed

Lines changed: 50 additions & 12 deletions

File tree

backend/src/lib/env-validation.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ function validateEnvironmentVariables() {
44
'SUPABASE_SERVICE_ROLE_KEY',
55
'STELLAR_NETWORK',
66
'DATABASE_URL',
7-
'REDIS_URL',
87
];
98

109
const missing = required.filter(key => !process.env[key]);
@@ -52,8 +51,12 @@ function validateEnvironmentVariables() {
5251
}
5352

5453
if (!process.env.RESEND_API_KEY) {
55-
console.warn("⚠️ RESEND_API_KEY is not set — receipt emails will be disabled.");
56-
}
54+
console.warn("⚠️ RESEND_API_KEY is not set — receipt emails will be disabled.");
55+
}
56+
57+
if (!process.env.REDIS_URL) {
58+
console.warn("⚠️ REDIS_URL is not set — running without Redis (fallback mode).");
59+
}
5760

5861
console.log('✅ Environment variables validated');
5962
}

backend/src/lib/redis.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,35 @@
11
import { createClient } from "redis";
22

33
let redisClient;
4+
let redisErrorCount = 0;
5+
6+
function getRedisConnectTimeoutMs(env = process.env) {
7+
const raw = Number.parseInt(String(env.REDIS_CONNECT_TIMEOUT_MS || "4000"), 10);
8+
if (!Number.isFinite(raw) || raw <= 0) return 4000;
9+
return raw;
10+
}
411

512
export function getRedisClient({
613
redisUrl = process.env.REDIS_URL,
714
clientFactory = createClient,
815
} = {}) {
916
if (!redisClient) {
10-
redisClient = clientFactory({ url: redisUrl });
17+
redisClient = clientFactory({
18+
url: redisUrl,
19+
socket: {
20+
connectTimeout: getRedisConnectTimeoutMs(),
21+
// Prevent endless reconnect loops when Redis URL is invalid/unreachable.
22+
reconnectStrategy: () => false,
23+
},
24+
});
1125
redisClient.on("error", (err) => {
12-
console.error("Redis client error:", err.message);
26+
redisErrorCount += 1;
27+
const suffix = err?.message ? ` ${err.message}` : "";
28+
if (redisErrorCount <= 3) {
29+
console.error("Redis client error:" + suffix);
30+
} else if (redisErrorCount === 4) {
31+
console.error("Redis client error: suppressing repeated logs");
32+
}
1333
});
1434
}
1535
return redisClient;
@@ -18,7 +38,18 @@ export function getRedisClient({
1838
export async function connectRedisClient(options) {
1939
const client = getRedisClient(options);
2040
if (!client.isOpen) {
21-
await client.connect();
41+
const timeoutMs = getRedisConnectTimeoutMs();
42+
const timeout = new Promise((_, reject) => {
43+
setTimeout(() => reject(new Error(`Redis connection timed out after ${timeoutMs}ms`)), timeoutMs);
44+
});
45+
try {
46+
await Promise.race([client.connect(), timeout]);
47+
} catch (err) {
48+
try {
49+
client.disconnect();
50+
} catch {}
51+
throw err;
52+
}
2253
}
2354
return client;
2455
}
@@ -91,4 +122,4 @@ export async function invalidatePaymentCache(client, id) {
91122
} catch (err) {
92123
console.error("Redis DEL error:", err.message);
93124
}
94-
}
125+
}

backend/src/server.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ const port = process.env.PORT || 4000;
1717

1818
async function startServer() {
1919
let redisClient = null;
20-
try {
21-
redisClient = await connectRedisClient();
22-
logger.info("redis connected");
23-
} catch (err) {
24-
logger.warn({ err }, "redis unavailable, continuing with in-memory fallbacks");
20+
if (process.env.REDIS_URL) {
21+
try {
22+
redisClient = await connectRedisClient();
23+
logger.info("redis connected");
24+
} catch (err) {
25+
logger.warn({ err }, "redis unavailable, continuing with in-memory fallbacks");
26+
}
27+
} else {
28+
logger.warn("redis disabled (REDIS_URL not set), using in-memory fallbacks");
2529
}
2630

2731
const { app, io } = await createApp({ redisClient });

0 commit comments

Comments
 (0)