Skip to content

fix: stop discarding errors that had somewhere to go - #140

Merged
meszmate merged 1 commit into
mainfrom
fix/stop-swallowing-errors
Aug 14, 2026
Merged

meszmate merged 1 commit into
mainfrom
fix/stop-swallowing-errors

Conversation

@meszmate

Copy link
Copy Markdown
Owner

Stacked on #132 — the layers example needs a fallible view to try the compositor.

Item 6 from the review: an audit of the 194 catch {} sites in src.

163 of them are in component view functions, where the signature genuinely cannot report anything. Those need the fallible-view treatment (#132) applied component by component and are left for a follow-up. This PR is the remaining 20 — the ones where an error was being dropped despite having a caller that could handle it.

LayerStack.render returned a truncated frame

const grid = allocator.alloc(Cell, w * h) catch return "";
...
writer.writeAll(cell.content) catch {};   // × 5

An out-of-memory frame reached the screen as an empty or half-drawn one, indistinguishable from a compositing bug. render is fallible now.

Image commands dropped real I/O failures

.cache_image and .delete_image swallowed everything, while .image_file immediately below them propagated. An unsupported protocol already returns false rather than erroring, so what was being discarded was genuine I/O failure — and a cache_image that quietly failed left the following place_cached_image drawing nothing, with no signal anywhere.

An append that cannot fail

dev_console did clearRetainingCapacity() then appendSlice(keep.items) catch {}. keep is a subset of what was just cleared, so the capacity is already there. appendSliceAssumeCapacity states the invariant instead of hiding behind a catch.

The rest are best-effort, and now say so

Terminal cleanup and the suspend path run while already unwinding, with nobody left to report to — a broken pipe must not stop the remaining modes from being reset. Those keep their catch {} and gain a comment explaining why, so the next reader does not have to work it out again.

Tests

A failing-allocator test walks the failure index across LayerStack.render and asserts the result is always either a whole frame or an error — never something in between.

zig build test and zig build clean on 0.16.0.

@meszmate
meszmate force-pushed the feat/fallible-model-callbacks branch from 1fb58a9 to 7d94d85 Compare August 14, 2026 04:37
@meszmate
meszmate changed the base branch from feat/fallible-model-callbacks to main August 14, 2026 04:42
An audit of the 194 `catch {}` sites in src. Most are in component
`view` functions, where the signature genuinely cannot report anything
-- those need the fallible-view treatment and are left for a follow-up.
These are the ones where an error was being dropped despite having a
caller that could handle it.

`LayerStack.render` returned `""` when the cell grid could not be
allocated and swallowed every write failure after that, so an
out-of-memory frame reached the screen as a truncated one, looking like
a compositing bug. It is fallible now.

The `.cache_image` and `.delete_image` commands dropped every error,
while `.image_file` right next to them propagated. An unsupported
protocol already returns false rather than erroring, so what was being
discarded was genuine I/O failure -- and a cache_image that quietly
failed left the following place_cached_image drawing nothing, with no
signal anywhere.

`dev_console` swallowed an append that cannot fail: the slice is a
subset of what was just cleared, so the capacity is already there.
`appendSliceAssumeCapacity` says so.

The rest -- terminal cleanup, the suspend path -- are best-effort by
nature: they run while unwinding, with nobody left to report to. Those
now carry a comment saying why, so the next reader does not have to
work it out again.
@meszmate
meszmate force-pushed the fix/stop-swallowing-errors branch from 6141588 to d1a2ca6 Compare August 14, 2026 04:50
@meszmate
meszmate merged commit 15259b0 into main Aug 14, 2026
12 checks passed
@meszmate
meszmate deleted the fix/stop-swallowing-errors branch August 28, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant