fix(query): add timeout settings entry to error page

This commit is contained in:
zipg authored and GitHub committed 2026-08-15 21:53:17 +08:00
1 parent 8f3351f720
commit 1d7fa00fe3
13 files changed
+113 -2

No files matched your search

+39 -1
View File
@@ -1,5 +1,43 @@
import { describe, expect, it } from "vitest";
import { isQueryTimeoutErrorMessage } from "@/lib/sql/queryError";
import { isConnectionTimeoutErrorMessage, isQueryTimeoutErrorMessage } from "@/lib/sql/queryError";
describe("isConnectionTimeoutErrorMessage", () => {
it("detects connection creation and handshake timeouts", () => {
expect(isConnectionTimeoutErrorMessage("PostgreSQL connection failed: Timeout occurred while creating a new object")).toBe(true);
expect(isConnectionTimeoutErrorMessage("MySQL connection failed: TLS handshake timed out after 10 seconds")).toBe(true);
expect(isConnectionTimeoutErrorMessage("The connection attempt timed out")).toBe(true);
});
it("detects structured connect-stage timeouts", () => {
const timeoutError = {
version: 1,
code: "DBX-JDBC-2001",
messageKey: "backendErrors.jdbc.operationTimedOut",
messageParams: { stage: "connect" },
source: "jdbcAgent",
operationOutcome: "not_started" as const,
} as const;
expect(isConnectionTimeoutErrorMessage("Database operation timed out (stage: connect).", timeoutError)).toBe(true);
});
it("does not classify query, pool checkout, cancellation, or syntax errors as connection timeouts", () => {
expect(isConnectionTimeoutErrorMessage("Query timed out after 30 seconds")).toBe(false);
expect(isConnectionTimeoutErrorMessage("PostgreSQL connection pool checkout timed out (5s)")).toBe(false);
expect(isConnectionTimeoutErrorMessage("Cancel request timed out after 10s.")).toBe(false);
expect(isConnectionTimeoutErrorMessage('syntax error at or near "select"')).toBe(false);
expect(
isConnectionTimeoutErrorMessage("Database operation timed out (stage: execute).", {
version: 1,
code: "DBX-JDBC-2002",
messageKey: "backendErrors.jdbc.operationTimedOut",
messageParams: { stage: "execute" },
source: "jdbcAgent",
operationOutcome: "unknown",
}),
).toBe(false);
});
});
describe("isQueryTimeoutErrorMessage", () => {
it("detects DBX query timeout messages", () => {
+14
View File
@@ -1,6 +1,20 @@
import type { BackendError } from "@/lib/backend/errorUtils";
const QUERY_TIMEOUT_STAGES = new Set(["execute", "fetch"]);
const CONNECTION_TIMEOUT_STAGES = new Set(["connect", "connection"]);
export function isConnectionTimeoutErrorMessage(message: string, backendError?: BackendError): boolean {
if (backendError?.messageKey === "backendErrors.jdbc.operationTimedOut") {
const stage = String(backendError.messageParams.stage ?? "").toLowerCase();
return CONNECTION_TIMEOUT_STAGES.has(stage);
}
const lower = message.toLowerCase();
if (/\btimeout occurred while creating a new object\b/.test(lower)) return true;
if (/\b(?:pool\s+checkout|checkout|metadata|loading|health check|cancel request)\b/.test(lower)) return false;
if (/\b(?:connection|connect|handshake)\b[\s\S]{0,80}\b(?:timed out|timeout expired|timeout exceeded|time-out)\b/.test(lower)) return true;
return /\b(?:timed out|timeout expired|timeout exceeded|time-out)\b[\s\S]{0,80}\b(?:connection attempt|connect|handshake)\b/.test(lower);
}
export function isQueryTimeoutErrorMessage(message: string, backendError?: BackendError): boolean {
if (backendError?.messageKey === "backendErrors.jdbc.operationTimedOut") {