Raise errors from the status registry instead of returning codes
akerr_reserve_status_range() and akerr_register_status_name() returned private int enumerations, which was the one place in the library where a failure was not an akerr_ErrorContext *. They now return one like everything else: NULL on success, and on refusal an error whose status is a real code in the library's reserved band, so it can be CATCH-ed, HANDLE-d, PASS-ed, or left to propagate into a stack trace. Both are marked AKERR_NOIGNORE, so discarding the result warns at compile time. AKERR_STATUS_RANGE_OK and AKERR_STATUS_NAME_OK are gone; the remaining seven codes move into the AKERR_* offset span and get registered names. AKERR_LAST_LIBRARY_STATUS replaces AKERR_BADEXC as the top of that span in the reserved-band static assert and the exhaustiveness sweep. The refusal detail that used to go straight to akerr_log_method now travels in the error message, so a caller that handles the error decides whether it is reported. The two-argument akerr_name_for_status() set path is the exception: it returns a name and cannot raise, so it logs and releases. akerr_init() likewise has no caller to raise into, so failing to reserve its own band or name its own codes is logged and fatal -- that can only happen on a misconfigured build, and continuing would degrade every later stack trace to "Unknown Error". Move the 1.0.0 upgrade notice out of README.md into UPGRADING.md and rewrite its return-code tables in terms of the statuses now raised. Tests: ctest 29/29, coverage 97.5% line / 64.5% branch, mutation 77.5% (was 77.6%; the new survivors are the fatal init path, which needs a library built with an undersized name table -- TODO item 7). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
This commit is contained in:
17
TODO.md
17
TODO.md
@@ -35,8 +35,8 @@ inside a loop" hazard: that comes from exiting via `break`, not from `switch`.
|
||||
## 3. No registry introspection
|
||||
|
||||
There is no way to ask who owns a status, or to enumerate reservations. The
|
||||
"coordinate ranges at the dependency-stack level" advice in README.md therefore
|
||||
has no tooling behind it.
|
||||
"coordinate ranges at the dependency-stack level" advice in UPGRADING.md
|
||||
therefore has no tooling behind it.
|
||||
|
||||
A read-only accessor plus a dump through `akerr_log_method` would let a startup
|
||||
self-check or a CI job print the whole map for a linked stack. Cheap, additive,
|
||||
@@ -63,6 +63,19 @@ exists for migration. Once consumers have moved to
|
||||
`akerr_register_status_name()`, make the set path a no-op or remove it and leave
|
||||
`akerr_name_for_status()` as pure lookup.
|
||||
|
||||
## 7. The library's own startup failure path is untested
|
||||
|
||||
`__akerr_name_library_status()` and the band reservation in `akerr_init()` log
|
||||
and then terminate when the library cannot name its own codes. Nothing exercises
|
||||
that: it needs a build whose `AKERR_STATUS_NAME_SLOTS` is too small to hold the
|
||||
library's own entries, and that macro is `PRIVATE` to the library target, so a
|
||||
test executable cannot set it. Mutation testing reports those lines as surviving
|
||||
mutants for this reason.
|
||||
|
||||
Closing it means a second library target built with a tiny table plus a
|
||||
`WILL_FAIL` test linked against it — worth doing when the CMake gains a
|
||||
sanitizer variant (item 1), since that adds the same machinery.
|
||||
|
||||
## Unrelated pre-existing issues
|
||||
|
||||
- The `AKERR_USE_STDLIB=OFF` build does not compile at all: `bool`, `PATH_MAX`
|
||||
|
||||
Reference in New Issue
Block a user