Filed from a field install on a restricted corporate network. Companion issues: log-hygiene (no info leak) and network-resilience.
Problem statement
When the install fails, PowerShell must never terminate ungracefully. Today it dies with a raw terminating-error dump — stack, source line, PS>TerminatingError() — leaving the user with a scary crash and no idea what happened or what to do. The user should always see a clean, human explanation of what happened during the installation and the exact next step; the window/session should never just die on them.
Observed (the field log):
PS>TerminatingError(): "cosign signature verification FAILED for manifest.sha256 -- refusing to install."
+ & $cosign @cosignArgs 2>$null 1>$null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (...) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Explanation (root cause)
The installer's failure paths are bare throws (and unhandled native-command stderr) with no try/catch around main(). An unhandled terminating error makes PowerShell print the raw error and end the script. There is no graceful closer, no classification of fatal vs recoverable, and no guaranteed "here's your log / here's what to do" message. So a network hiccup surfaces as a crash instead of a diagnosis.
Proposed solution
- A single top-level
try / catch / finally (+ trap) in the bootstrap and the main installer. The catch renders one clean, branded block — what failed, why in plain terms, the exact next steps, and where the log is — then exit <code>. No stack, no source line, ever. - Classify failures fatal vs recoverable. Optional/recoverable steps warn and continue (the GPU-toolkit timeout already does this correctly — "GPU not set up, continuing in CPU mode"). Only a genuine can't-proceed stops — and stops cleanly. Apply that pattern consistently.
- Every native call bounded + exit-code-checked (the installer already has
Invoke-Bounded / Wait-ProcessWithDeadline; the raw & $cosign at line 360 was the one that slipped through and became a crash). A wedged or erroring tool becomes a handled condition, never a terminating error. - A guaranteed
finally that always prints "Log saved to … — send it to support if you're stuck" and stops the transcript cleanly, so the window never just disappears.
This is the substrate the other two issues rely on: it's what converts a network block into "your network is blocking X — here's what to do" instead of a stack dump.
Severity: Tier 1 — UX / trust. Confidence: CONFIRMED.
Filed from a field install on a restricted corporate network. Companion issues: log-hygiene (no info leak) and network-resilience.
Problem statement
When the install fails, PowerShell must never terminate ungracefully. Today it dies with a raw terminating-error dump — stack, source line,
PS>TerminatingError()— leaving the user with a scary crash and no idea what happened or what to do. The user should always see a clean, human explanation of what happened during the installation and the exact next step; the window/session should never just die on them.Observed (the field log):
Explanation (root cause)
The installer's failure paths are bare
throws (and unhandled native-command stderr) with notry/catcharoundmain(). An unhandled terminating error makes PowerShell print the raw error and end the script. There is no graceful closer, no classification of fatal vs recoverable, and no guaranteed "here's your log / here's what to do" message. So a network hiccup surfaces as a crash instead of a diagnosis.Proposed solution
try / catch / finally(+trap) in the bootstrap and the main installer. Thecatchrenders one clean, branded block — what failed, why in plain terms, the exact next steps, and where the log is — thenexit <code>. No stack, no source line, ever.Invoke-Bounded/Wait-ProcessWithDeadline; the raw& $cosignat line 360 was the one that slipped through and became a crash). A wedged or erroring tool becomes a handled condition, never a terminating error.finallythat always prints "Log saved to … — send it to support if you're stuck" and stops the transcript cleanly, so the window never just disappears.This is the substrate the other two issues rely on: it's what converts a network block into "your network is blocking X — here's what to do" instead of a stack dump.
Severity: Tier 1 — UX / trust. Confidence: CONFIRMED.