From 40a21ba767d908f9e1f7e0117c33f30c08ad4613 Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 3 Aug 2026 19:42:20 +0200 Subject: [PATCH] fix: wrap SSE state updates in flushSync to resolve React error #418 --- src/app/admin/import/audit/audit-client.tsx | 135 ++++++++++---------- 1 file changed, 69 insertions(+), 66 deletions(-) diff --git a/src/app/admin/import/audit/audit-client.tsx b/src/app/admin/import/audit/audit-client.tsx index d2bf0b17..7eb129e3 100644 --- a/src/app/admin/import/audit/audit-client.tsx +++ b/src/app/admin/import/audit/audit-client.tsx @@ -10,6 +10,7 @@ import { SearchX, } from "lucide-react"; import { useCallback, useRef, useState } from "react"; +import { flushSync } from "react-dom"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { adminFetch } from "@/lib/admin-fetch"; @@ -246,80 +247,82 @@ export function AuditClient() { try { const evt = JSON.parse(part.slice(6)) as AuditEvent; - if (evt.type === "progress") { - setProgress(evt.message ?? ""); - } + flushSync(() => { + if (evt.type === "progress") { + setProgress(evt.message ?? ""); + } - if (evt.type === "items_loaded") { - setProgress(`Loaded ${evt.total} items_base entries`); - } + if (evt.type === "items_loaded") { + setProgress(`Loaded ${evt.total} items_base entries`); + } - if (evt.type === "catalog_loaded") { - setProgress(`Loaded ${evt.total} catalog_items entries`); - } + if (evt.type === "catalog_loaded") { + setProgress(`Loaded ${evt.total} catalog_items entries`); + } - if (evt.type === "checking") { - setProgress(`Checking ${evt.section}…`); - if (evt.total) { - setCheckProgress({ - section: evt.section ?? "", - current: evt.current ?? 0, - total: evt.total, + if (evt.type === "checking") { + setProgress(`Checking ${evt.section}…`); + if (evt.total) { + setCheckProgress({ + section: evt.section ?? "", + current: evt.current ?? 0, + total: evt.total, + }); + } + } + + if (evt.type === "repair_complete") { + if (evt.repair) setRepairStats(evt.repair); + if (evt.repairNitro) setNitroRepairStats(evt.repairNitro); + } + + if (evt.type === "sql_ready") { + setSqlText(evt.sql ?? null); + } + + if (evt.type === "sql_applied") { + setSqlApplied({ + applied: evt.applied ?? 0, + failed: evt.sqlFailed ?? 0, }); } - } - if (evt.type === "repair_complete") { - if (evt.repair) setRepairStats(evt.repair); - if (evt.repairNitro) setNitroRepairStats(evt.repairNitro); - } - - if (evt.type === "sql_ready") { - setSqlText(evt.sql ?? null); - } - - if (evt.type === "sql_applied") { - setSqlApplied({ - applied: evt.applied ?? 0, - failed: evt.sqlFailed ?? 0, - }); - } - - if (evt.type === "furnidata_repair_complete") { - if (evt.furniData) setFurniDataResult(evt.furniData); - } - - if (evt.type === "structure_repair_complete") { - if (evt.structure) setStructureResult(evt.structure); - } - - if (evt.type === "batch_complete") { - setIssues(evt.issues ?? []); - setMissingFromSources(evt.missingFromSources ?? []); - if (evt.summary) setSummary(evt.summary); - setCheckProgress(null); - setProgress("Done"); - if ( - evt.issues && - evt.issues.filter((i) => i.severity === "error").length > 0 - ) { - toast.error( - `${evt.issues.filter((i) => i.severity === "error").length} error(s) found`, - ); - } else if ( - evt.issues && - evt.issues.filter((i) => i.severity === "warning").length > 0 - ) { - toast.warning("Warnings found"); - } else { - toast.success("No issues found"); + if (evt.type === "furnidata_repair_complete") { + if (evt.furniData) setFurniDataResult(evt.furniData); } - } - if (evt.type === "error") { - setProgress(`ERROR: ${evt.message ?? ""}`); - toast.error(evt.message ?? "Audit failed"); - } + if (evt.type === "structure_repair_complete") { + if (evt.structure) setStructureResult(evt.structure); + } + + if (evt.type === "batch_complete") { + setIssues(evt.issues ?? []); + setMissingFromSources(evt.missingFromSources ?? []); + if (evt.summary) setSummary(evt.summary); + setCheckProgress(null); + setProgress("Done"); + if ( + evt.issues && + evt.issues.filter((i) => i.severity === "error").length > 0 + ) { + toast.error( + `${evt.issues.filter((i) => i.severity === "error").length} error(s) found`, + ); + } else if ( + evt.issues && + evt.issues.filter((i) => i.severity === "warning").length > 0 + ) { + toast.warning("Warnings found"); + } else { + toast.success("No issues found"); + } + } + + if (evt.type === "error") { + setProgress(`ERROR: ${evt.message ?? ""}`); + toast.error(evt.message ?? "Audit failed"); + } + }); } catch { // skip parse errors }