Failsafe workflow
The failsafe family is Nitpick's final safety net. v0.34.x hardens where it can be called, what shape it must have, and which runtime contract violations route through it.
Required endpoints
Every program defines main and failsafe:
func:failsafe = int32(tbb32:err) {
exit 1;
};
func:main = int32() {
exit 0;
};
mainis the program entry point.failsafereceives an unrecoverabletbb32error code.- Both endpoints exit with
exit, notpassorfail.
Exit scope
v0.34.2 locks exit scope:
- allowed inside
main; - allowed inside
failsafe; - rejected in ordinary, async, or comptime helper functions.
Diagnostic:
ARIA-069: ARIA-EXIT-ELSEWHERE
Failsafe must exit
v0.34.1 locks failsafe as an endpoint that cannot fall through:
func:failsafe = int32(tbb32:err) {
if (err == 49i32) { exit 49; }
exit 1;
};
A reachable path that returns or falls off the end is rejected with:
ARIA-068: ARIA-FAILSAFE-NO-EXIT
!!! dispatch
The !!! shorthand dispatches to failsafe and marks the path unreachable:
func:failsafe = int32(tbb32:err) {
exit 1;
};
func:main = int32() {
!!! 47i32;
exit 0;
};
Use it for explicit unrecoverable paths, not ordinary Result fallback. Source
expr ?! fallback remains Result fallback unwrap, not failsafe dispatch.
v0.34.x error-code table
| Code | Meaning |
|---|---|
45 |
Existing out-of-bounds sentinel from earlier memory/bounds work. |
47 |
kFailsafeEmphaticUnwrapErrCode, ratified from the v0.33.x reservation. |
48 |
Contract/invariant debug runtime failure path used by v0.34.x contract checks. |
49 |
Runtime limit<Rules> declaration/assignment violation. |
The exact stdlib names live in stdlib/failsafe_codes.npk in the compiler repo.
Workflow checklist
- Define
failsafefirst in examples and tests. - Keep it deterministic and side-effect-light.
- Match known error codes explicitly when a test needs exact behavior.
- End every path with
exitor!!!. - Use Result
failfor recoverable errors; reservefailsafefor final safety net violations.