From 6e0077bd4dfd2cdaf74cf44555137c3587bb684f Mon Sep 17 00:00:00 2001 From: IK Date: Thu, 10 Sep 2026 05:43:34 +0700 Subject: [PATCH] =?UTF-8?q?R10:=20Fix=20TimeoutError=20handling=20?= =?UTF-8?q?=E2=80=94=20use=20DOMException.TimeoutError=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AbortSignal.timeout() throws DOMException with name='TimeoutError', not TypeError - Check for DOMException.TimeoutError, TypeError(fetch), or Error(abort) - Apply same fix to report.ts and report-screenshot.ts - Timeout redirects to 'timeout' state, other errors to 'create_error' --- apps/web/src/pages/api/report-screenshot.ts | 7 ++++++- apps/web/src/pages/api/report.ts | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/web/src/pages/api/report-screenshot.ts b/apps/web/src/pages/api/report-screenshot.ts index 5c42faa..30b95c2 100644 --- a/apps/web/src/pages/api/report-screenshot.ts +++ b/apps/web/src/pages/api/report-screenshot.ts @@ -14,5 +14,10 @@ export const POST: APIRoute = async ({ request, redirect, cookies }) => { const response = await fetch(`${base}/api/v1/catch-reports/${reportId}/screenshot`, { method: "POST", headers:{"X-Upload-Token":uploadToken}, body: upload, signal: AbortSignal.timeout(60_000) }); if (response.ok) cookies.delete(cookieName, {path:"/"}); return redirect(response.ok ? "/report?state=screenshot_sent" : `/report?state=screenshot_error&report_id=${encodeURIComponent(reportId)}`, 303); - } catch { return redirect(`/report?state=screenshot_error&report_id=${encodeURIComponent(reportId)}`, 303); } + } catch (err) { + const isTimeout = err instanceof DOMException && err.name === "TimeoutError" || + err instanceof TypeError && err.message.toLowerCase().includes("fetch") || + err instanceof Error && err.message.toLowerCase().includes("abort"); + return redirect(isTimeout ? `/report?state=timeout&report_id=${encodeURIComponent(reportId)}` : `/report?state=screenshot_error&report_id=${encodeURIComponent(reportId)}`, 303); + } }; diff --git a/apps/web/src/pages/api/report.ts b/apps/web/src/pages/api/report.ts index 4b2c900..79de7ef 100644 --- a/apps/web/src/pages/api/report.ts +++ b/apps/web/src/pages/api/report.ts @@ -35,7 +35,10 @@ export const POST: APIRoute = async ({ request, redirect, cookies }) => { return redirect("/report?state=sent", 303); } catch (err) { - if (err instanceof TypeError && err.message.includes("abort")) { + const isTimeout = err instanceof DOMException && err.name === "TimeoutError" || + err instanceof TypeError && err.message.toLowerCase().includes("fetch") || + err instanceof Error && err.message.toLowerCase().includes("abort"); + if (isTimeout) { if (createdId && uploadToken) cookies.set(`rf4-upload-${createdId}`, uploadToken, {httpOnly:true, sameSite:"strict", secure:import.meta.env.PROD, path:"/", maxAge:3600}); return redirect(createdId ? `/report?state=screenshot_error&report_id=${encodeURIComponent(createdId)}` : "/report?state=timeout", 303); }