Files
AeroFetch/src/renderer/src/components/ErrorBoundary.tsx
T
debont80 1376c2dee8 Harden audit findings: correctness, type-safety, Windows conventions & polish
Audit-pass over CODE-AUDIT.md (~48 items closed this pass; all verified —
typecheck + 234 tests + eslint + prettier green).

Correctness / bugs:
- B3: match the release checksum to the asset's filename line (no wrong-hash verify)
- B4: newline-safe metadata probe (one --print with a unit-separator delimiter)
- B5 / L88: guard the meta event against canceled items; progress no longer promotes
  a queued item outside pump()
- B7: cookie-login promise always resolves (handles destroy-without-close)
- L146: trim parser rejects >2 colon-group times; M36: Library selection counts only
  actionable rows
- L11 / L50 / L156 / L57 / L159 / L15 / L3: live queue count, empty-cookie message,
  schedule picker min, dead-code/comment cleanup

Type safety:
- Enable noUncheckedIndexedAccess + noFallthroughCasesInSwitch (15 real edge cases fixed)

Resilience / Windows / metadata:
- R5: settings write failure handled (no unhandled IPC rejection; reconciles to truth)
- W1 / W5 / W6: min window size, seeded folder picker, parented sign-in window;
  L147 dead macOS branches removed
- CL1: shared stdout markers; package/builder metadata (license, homepage, repository,
  copyright, tsbuildinfo glob)

Copy / docs / tests:
- M37 / SR9 dev-jargon cleanup in hints; M8 / M25 / M26 / L66 / L80 / L81 reconciled
- New unit tests for L35 (isValidMediaItem) and L36 (compareVersions)

This commit also checkpoints the previously-uncommitted feat/tray-background-clipboard
work it builds on: background running + auto-download, library clipboard detection,
tray, binary management & library scale, credential encryption at rest, the shared
jsonStore and ui/ primitives, and the eslint/prettier tooling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 13:02:54 -04:00

101 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react'
interface Props {
children: React.ReactNode
}
interface State {
error: Error | null
}
/**
* Top-level renderer error boundary (M16). Before this, an exception thrown in
* render by any view unmounted the whole shell to a blank white window with no
* way out. This catches it, logs it (so it reaches the dev console / future log
* sink), and shows a recover affordance.
*
* The fallback is intentionally dependency-free — no Fluent components, no theme
* provider — because the error may have come from inside that very tree. It paints
* its own full-window dark surface (matching the app's dark charcoal + toffee
* accent) rather than reading theme tokens, so it renders identically regardless
* of the active theme and uses only inline CSS that can't itself throw.
*/
export class ErrorBoundary extends React.Component<Props, State> {
state: State = { error: null }
static getDerivedStateFromError(error: Error): State {
return { error }
}
componentDidCatch(error: Error, info: React.ErrorInfo): void {
console.error('[AeroFetch] renderer crashed:', error, info.componentStack)
}
private handleReload = (): void => {
// A full reload re-runs the renderer from a clean state; persisted data
// (settings/history/sources) lives in main, so nothing is lost.
window.location.reload()
}
render(): React.ReactNode {
const { error } = this.state
if (!error) return this.props.children
return (
<div
role="alert"
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: 16,
minHeight: '100vh',
padding: 32,
textAlign: 'center',
fontFamily: 'Segoe UI, system-ui, sans-serif',
color: '#c8c6c4',
background: '#201f1e'
}}
>
<div style={{ fontSize: 18, fontWeight: 600, color: '#f3f2f1' }}>Something went wrong</div>
<div style={{ maxWidth: 440, fontSize: 13, lineHeight: 1.5 }}>
AeroFetch hit an unexpected error and couldnt continue. Your downloads and settings are
saved reloading the window should bring you back.
</div>
<pre
style={{
maxWidth: 480,
maxHeight: 120,
overflow: 'auto',
margin: 0,
padding: '8px 12px',
fontSize: 11,
textAlign: 'left',
color: '#d29ca0',
background: '#2b2a29',
borderRadius: 6
}}
>
{error.message || String(error)}
</pre>
<button
type="button"
onClick={this.handleReload}
style={{
padding: '8px 20px',
fontSize: 14,
fontWeight: 600,
color: '#1c1611',
background: '#b5917d',
border: 'none',
borderRadius: 8,
cursor: 'pointer'
}}
>
Reload AeroFetch
</button>
</div>
)
}
}