File tree Expand file tree Collapse file tree 4 files changed +56
-20
lines changed
Expand file tree Collapse file tree 4 files changed +56
-20
lines changed Original file line number Diff line number Diff line change @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
88## [ Unreleased]
99
10+ ## [ 6.3.3] - 2026-03-13
11+
12+ ### Fixed
13+
14+ - Fixed ` /health ` timeout race condition where the timeout log would fire even when the DB connection succeeded in time
15+
1016## [ 6.3.2] - 2026-03-11
1117
1218### Changed
Original file line number Diff line number Diff line change 11{
22 "name" : " blockfrost-backend-ryo" ,
3- "version" : " 6.3.2 " ,
3+ "version" : " 6.3.3 " ,
44 "description" : " " ,
55 "keywords" : [],
66 "license" : " Apache-2.0" ,
Original file line number Diff line number Diff line change @@ -18,25 +18,30 @@ async function route(fastify: FastifyInstance) {
1818 let dbHealthy = true ;
1919
2020 if ( healthCheckDbTimeoutMs !== undefined ) {
21- const connected = await Promise . race ( [
22- getDbSync ( fastify )
23- . then ( client => {
24- client . release ( ) ;
25- return true ;
26- } )
27- . catch ( ( error : unknown ) => {
28- console . error ( `[HEALTH]: unhealthy — DB connection error` , error ) ;
29- return false ;
30- } ) ,
31- new Promise < boolean > ( resolve =>
32- setTimeout ( ( ) => {
33- console . error (
34- `[HEALTH]: unhealthy — DB connection timed out after ${ healthCheckDbTimeoutMs } ms` ,
35- ) ;
36- resolve ( false ) ;
37- } , healthCheckDbTimeoutMs ) ,
38- ) ,
39- ] ) ;
21+ let timer : ReturnType < typeof setTimeout > | undefined ;
22+
23+ const dbPromise = getDbSync ( fastify )
24+ . then ( client => {
25+ clearTimeout ( timer ) ;
26+ client . release ( ) ;
27+ return true ;
28+ } )
29+ . catch ( ( error : unknown ) => {
30+ clearTimeout ( timer ) ;
31+ console . error ( `[HEALTH]: unhealthy — DBSync connection error` , error ) ;
32+ return false ;
33+ } ) ;
34+
35+ const timeoutPromise = new Promise < boolean > ( resolve => {
36+ timer = setTimeout ( ( ) => {
37+ console . error (
38+ `[HEALTH]: unhealthy — DBSync did not respond within ${ healthCheckDbTimeoutMs } ms` ,
39+ ) ;
40+ resolve ( false ) ;
41+ } , healthCheckDbTimeoutMs ) ;
42+ } ) ;
43+
44+ const connected = await Promise . race ( [ dbPromise , timeoutPromise ] ) ;
4045
4146 if ( ! connected ) {
4247 dbHealthy = false ;
Original file line number Diff line number Diff line change @@ -66,4 +66,29 @@ describe('health endpoints tests', () => {
6666
6767 fastify . close ( ) ;
6868 } ) ;
69+
70+ test ( 'does not log timeout error when DB responds before healthCheckDbTimeoutMs' , async ( ) => {
71+ // Use a short timeout so we can wait past it and verify the log never fires
72+ mainConfig . server . healthCheckDbTimeoutMs = 50 ;
73+
74+ const fastify = buildFastify ( ) ;
75+ const errorSpy = vi . spyOn ( console , 'error' ) ;
76+
77+ vi . spyOn ( databaseUtils , 'getDbSync' ) . mockReturnValue (
78+ // @ts -expect-error test
79+ Promise . resolve ( { release : ( ) => null } ) ,
80+ ) ;
81+
82+ await fastify . ready ( ) ;
83+ const response = await supertest ( fastify . server ) . get ( '/health' ) ;
84+
85+ expect ( response . body ) . toEqual ( { is_healthy : true } ) ;
86+
87+ // Wait past the timeout to ensure the timer was actually cancelled
88+ await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
89+
90+ expect ( errorSpy ) . not . toHaveBeenCalledWith ( expect . stringContaining ( 'did not respond within' ) ) ;
91+
92+ fastify . close ( ) ;
93+ } ) ;
6994} ) ;
You can’t perform that action at this time.
0 commit comments