fix(metrics): guard toFixed() calls against undefined/null values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-07 09:34:05 -08:00
parent 149939f5f0
commit 23daa8e122
1 changed files with 12 additions and 11 deletions

View File

@ -164,17 +164,18 @@ function EnvironmentBadge({ env }: { env: ServerMetric['environment'] }) {
// Percent bar
// ---------------------------------------------------------------------------
function PercentBar({ value, label }: { value: number; label?: string }) {
function PercentBar({ value, label }: { value: number | null | undefined; label?: string }) {
const v = value ?? 0;
return (
<div className="flex items-center gap-2 min-w-[120px]">
<div className="flex-1 h-2 bg-muted rounded-full overflow-hidden">
<div
className={cn('h-full rounded-full transition-all', getPercentBarColor(value))}
style={{ width: `${Math.min(value, 100)}%` }}
className={cn('h-full rounded-full transition-all', getPercentBarColor(v))}
style={{ width: `${Math.min(v, 100)}%` }}
/>
</div>
<span className={cn('text-xs font-medium tabular-nums w-10 text-right', getPercentColor(value))}>
{value.toFixed(1)}%
<span className={cn('text-xs font-medium tabular-nums w-10 text-right', getPercentColor(v))}>
{v.toFixed(1)}%
</span>
{label && <span className="text-xs text-muted-foreground">{label}</span>}
</div>
@ -360,21 +361,21 @@ export default function MetricsPage() {
/>
<OverviewCard
label={t('metrics.overview.online')}
value={`${overview.onlinePercent.toFixed(1)}`}
value={`${(overview.onlinePercent ?? 0).toFixed(1)}`}
suffix="%"
color={overview.onlinePercent >= 95 ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'}
color={(overview.onlinePercent ?? 0) >= 95 ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'}
/>
<OverviewCard
label={t('metrics.overview.avgCpu')}
value={`${overview.avgCpuPercent.toFixed(1)}`}
value={`${(overview.avgCpuPercent ?? 0).toFixed(1)}`}
suffix="%"
color={getPercentColor(overview.avgCpuPercent)}
color={getPercentColor(overview.avgCpuPercent ?? 0)}
/>
<OverviewCard
label={t('metrics.overview.avgMemory')}
value={`${overview.avgMemoryPercent.toFixed(1)}`}
value={`${(overview.avgMemoryPercent ?? 0).toFixed(1)}`}
suffix="%"
color={getPercentColor(overview.avgMemoryPercent)}
color={getPercentColor(overview.avgMemoryPercent ?? 0)}
/>
<OverviewCard
label={t('metrics.overview.alertsToday')}