Skip to content

Commit a70817e

Browse files
committed
feat(gas-profiler): show friendly syncing state when backend nodes are unavailable
Replace generic error alerts with dedicated UI when the proxy returns 503 "currently syncing". Users now see an animated spinner and clear message instead of a raw error, reducing confusion during node sync.
1 parent 872153c commit a70817e

File tree

1 file changed

+75
-9
lines changed

1 file changed

+75
-9
lines changed

src/pages/ethereum/execution/gas-profiler/SimulatePage.tsx

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,19 @@ function getDeltaColor(percent: number): string {
105105
return 'text-muted';
106106
}
107107

108+
/** Detect backend syncing errors (503 from the proxy). */
109+
function isSyncingError(error: unknown): boolean {
110+
if (error instanceof Error) {
111+
return error.message.includes('currently syncing');
112+
}
113+
114+
if (typeof error === 'string') {
115+
return error.includes('currently syncing');
116+
}
117+
118+
return false;
119+
}
120+
108121
function calculateAggregateStats(results: BlockSimulationResult[]): AggregateStats {
109122
const stats = results.reduce(
110123
(acc, result) => {
@@ -824,14 +837,37 @@ export function SimulatePage(): JSX.Element {
824837
Loading gas parameters...
825838
</div>
826839
)}
827-
{defaultsError && (
828-
<Alert
829-
variant="error"
830-
description={`Error loading gas schedule: ${defaultsError.message}`}
831-
accentBorder
832-
className="mt-3"
833-
/>
834-
)}
840+
{defaultsError &&
841+
(isSyncingError(defaultsError) ? (
842+
<div
843+
className="mt-3 overflow-hidden rounded-sm border border-amber-400/30 dark:border-amber-500/20"
844+
role="status"
845+
aria-live="polite"
846+
>
847+
<div className="flex items-start gap-3 bg-amber-50/80 p-3.5 dark:bg-amber-500/5">
848+
<div className="flex size-8 shrink-0 items-center justify-center rounded-xs bg-amber-100 dark:bg-amber-500/15">
849+
<ArrowPathIcon
850+
className="size-4 animate-spin text-amber-600 dark:text-amber-400"
851+
style={{ animationDuration: '2s' }}
852+
/>
853+
</div>
854+
<div className="min-w-0 flex-1">
855+
<p className="text-sm/5 font-medium text-amber-800 dark:text-amber-200">Backend nodes are syncing</p>
856+
<p className="mt-0.5 text-xs/4 text-amber-700/70 dark:text-amber-300/60">
857+
The nodes serving this network are catching up with the chain. Check back shortly and try again.
858+
</p>
859+
</div>
860+
</div>
861+
<div className="h-px animate-pulse bg-linear-to-r from-transparent via-amber-400/50 to-transparent" />
862+
</div>
863+
) : (
864+
<Alert
865+
variant="error"
866+
description={`Error loading gas schedule: ${defaultsError.message}`}
867+
accentBorder
868+
className="mt-3"
869+
/>
870+
))}
835871
{gasWarning && modifiedCount === 0 && (
836872
<Alert
837873
variant="warning"
@@ -946,7 +982,37 @@ export function SimulatePage(): JSX.Element {
946982
{/* Error */}
947983
{simState.status === 'error' && (
948984
<div className="mb-4">
949-
<Alert variant="error" title="Simulation failed" description={simState.error ?? 'Unknown error'} />
985+
{isSyncingError(simState.error) ? (
986+
<Card className="overflow-hidden">
987+
<div className="flex items-start gap-4 p-5" role="status" aria-live="polite">
988+
<div className="relative flex size-10 shrink-0 items-center justify-center">
989+
<div
990+
className="absolute inset-0 animate-ping rounded-full bg-amber-400/15"
991+
style={{ animationDuration: '3s' }}
992+
/>
993+
<div className="flex size-10 items-center justify-center rounded-full bg-amber-100 dark:bg-amber-500/10">
994+
<ArrowPathIcon
995+
className="size-5 animate-spin text-amber-500 dark:text-amber-400"
996+
style={{ animationDuration: '2s' }}
997+
/>
998+
</div>
999+
</div>
1000+
<div className="min-w-0 flex-1">
1001+
<h3 className="text-sm font-semibold text-foreground">Backend Syncing</h3>
1002+
<p className="mt-1 text-sm/5 text-muted">
1003+
The simulation was interrupted because all backend nodes for this network are currently syncing with
1004+
the chain.
1005+
{simState.completedBlocks > 0 &&
1006+
` ${simState.completedBlocks} of ${simState.totalBlocks} blocks completed before the interruption.`}{' '}
1007+
Check back shortly and try again.
1008+
</p>
1009+
</div>
1010+
</div>
1011+
<div className="h-px animate-pulse bg-linear-to-r from-transparent via-amber-400/40 to-transparent" />
1012+
</Card>
1013+
) : (
1014+
<Alert variant="error" title="Simulation failed" description={simState.error ?? 'Unknown error'} />
1015+
)}
9501016
</div>
9511017
)}
9521018

0 commit comments

Comments
 (0)