From ccf18fe9044b6eac45740a0a6c66d562be69c768 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Tue, 16 Jun 2026 22:02:04 +0800 Subject: [PATCH] Prevent refetch on focus and reconnect for /query requests that failed due to statement timeouts (#46972) ## Context As per PR title - prevents refetch on focus and reconnect for /query requests that failed due to statement timeouts, presumably that those requests will run into the same problem either way so this minimizes unnecessary impact to the database ## Summary by CodeRabbit * **Bug Fixes** * Improved handling of statement timeouts to prevent automatic retry attempts after window focus or reconnection. * Enhanced query execution request identification for better query tracking. --- apps/studio/data/query-client.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/apps/studio/data/query-client.ts b/apps/studio/data/query-client.ts index 43306d39139..6f7b578c6a5 100644 --- a/apps/studio/data/query-client.ts +++ b/apps/studio/data/query-client.ts @@ -20,6 +20,16 @@ const SKIP_RETRY_PATHNAME_MATCHERS = [ export const MAX_RETRY_FAILURE_COUNT = 3 +function isQueryEndpointStatementTimeout(error: unknown) { + const PG_META_QUERY_PATHNAME_MATCHER = match('/platform/pg-meta/:ref/query') + return ( + error instanceof ResponseError && + !!error.requestPathname && + !!PG_META_QUERY_PATHNAME_MATCHER(error.requestPathname) && + !!error.message?.includes('canceling statement due to statement timeout') + ) +} + let queryClient: QueryClient | undefined export function getQueryClient() { @@ -71,6 +81,17 @@ export function getQueryClient() { // react-query default: doubles, starting at 1000ms, with each attempt, but will not exceed 30 seconds return Math.min(1000 * 2 ** failureCount, 30000) }, + refetchOnWindowFocus(query) { + // [Joshen] Opting to not refetch a /query request that failed due to a statement + // timeout, presumably that it'll just run into the same issue. Can however be overriden + // on a per case basis on each individual query hook + if (isQueryEndpointStatementTimeout(query.state.error)) return false + return true + }, + refetchOnReconnect(query) { + if (isQueryEndpointStatementTimeout(query.state.error)) return false + return true + }, }, }, })