Skip to content

formatBytes returns wrong unit for >= 1 PiB and crashes on negative/NaN #15

Description

@bouncia

frontend/src/lib/utils.ts:22-28:

export function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`
}

Two edge cases:

formatBytes(1024 ** 5)   // i = 5, sizes[5] = undefined → "1.0 undefined"
formatBytes(-1)          // Math.log(-1) = NaN, i = NaN, sizes[NaN] = undefined → "NaN undefined"
formatBytes(NaN)         // same as above
formatBytes(0.5)         // i = -1, sizes[-1] = undefined → "0.5 undefined"

This is mostly cosmetic but it shows up in frontend/src/pages/System/Metrics.tsx (renders artifact sizes from Artifact.sizeBytes defined in frontend/src/lib/api/jobs.ts:59), so a corrupt size from the backend produces a NaN undefined cell, which then breaks the table header alignment in frontend/src/components/experiments/MetricsTable.tsx.

Fix

export function formatBytes(bytes: number): string {
  if (!Number.isFinite(bytes) || bytes < 0) return '–'
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']
  const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1)
  return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions