11// app/api/health/redis/route.ts
2- import { NextResponse } from "next/server" ;
3- import { redis } from "@/lib/redis" ;
2+ import { NextResponse } from 'next/server' ;
3+ import { redis , getHealth } from '@/lib/redis' ;
4+
5+ export const dynamic = 'force-dynamic' ;
46
57export async function GET ( ) {
8+ const health = getHealth ( ) ;
9+
10+ // If Redis isn't initialized, return immediately
611 if ( ! redis ) {
7- return NextResponse . json ( { status : "Redis not configured" } , { status : 503 } ) ;
12+ return NextResponse . json (
13+ {
14+ status : 'unavailable' ,
15+ initialized : false ,
16+ error : 'Redis client not initialized' ,
17+ timestamp : new Date ( ) . toISOString ( ) ,
18+ } ,
19+ { status : 503 }
20+ ) ;
21+ }
22+
23+ // If circuit breaker is open, don't attempt ping
24+ if ( health . circuitBreakerOpen ) {
25+ return NextResponse . json (
26+ {
27+ status : 'unhealthy' ,
28+ connected : false ,
29+ error : 'Circuit breaker is open' ,
30+ ...health ,
31+ timestamp : new Date ( ) . toISOString ( ) ,
32+ } ,
33+ { status : 503 }
34+ ) ;
835 }
936
37+ // Perform real connectivity check
38+ const startTime = Date . now ( ) ;
39+
1040 try {
11- await redis . ping ( ) ;
12- return NextResponse . json ( { status : "healthy" , timestamp : new Date ( ) . toISOString ( ) } ) ;
41+ const pingResult = await Promise . race ( [
42+ redis . ping ( ) ,
43+ new Promise < null > ( ( _ , reject ) =>
44+ setTimeout (
45+ ( ) => reject ( new Error ( 'Ping timed out after 3s' ) ) ,
46+ 3000
47+ )
48+ ) ,
49+ ] ) ;
50+
51+ const latency = Date . now ( ) - startTime ;
52+
53+ if ( pingResult === 'PONG' ) {
54+ return NextResponse . json (
55+ {
56+ status : 'healthy' ,
57+ connected : true ,
58+ latency,
59+ ...health ,
60+ timestamp : new Date ( ) . toISOString ( ) ,
61+ } ,
62+ { status : 200 }
63+ ) ;
64+ }
65+
66+ return NextResponse . json (
67+ {
68+ status : 'degraded' ,
69+ connected : false ,
70+ latency,
71+ error : `Unexpected ping response: ${ typeof pingResult } ` ,
72+ ...health ,
73+ timestamp : new Date ( ) . toISOString ( ) ,
74+ } ,
75+ { status : 503 }
76+ ) ;
1377 } catch ( error ) {
14- return NextResponse . json ( { status : "unhealthy" , error : String ( error ) } , { status : 503 } ) ;
78+ const latency = Date . now ( ) - startTime ;
79+ const errorMessage = error instanceof Error ? error . message : 'Unknown error' ;
80+
81+ let status : string = 'unhealthy' ;
82+ let diagnostic = errorMessage ;
83+
84+ if ( errorMessage . includes ( 'ENOTFOUND' ) || errorMessage . includes ( 'getaddrinfo' ) ) {
85+ diagnostic = `DNS resolution failed: ${ errorMessage } ` ;
86+ } else if ( errorMessage . includes ( 'timed out' ) ) {
87+ status = 'degraded' ;
88+ }
89+
90+ return NextResponse . json (
91+ {
92+ status,
93+ connected : false ,
94+ latency,
95+ error : diagnostic ,
96+ ...health ,
97+ timestamp : new Date ( ) . toISOString ( ) ,
98+ } ,
99+ { status : 503 }
100+ ) ;
15101 }
16102}
0 commit comments