feat!: one ErrorCode space every binding reports - #883
Merged
Conversation
`odr::ErrorCode` replaces five hand-maintained lists of the same fifteen exception kinds — the ladders in `odr_jni.cpp`, `ODRInternal.mm`, `odr_wasm.cpp` and `bind_core.cpp` — and takes in the codes the rendered page raises for a refused edit, which lived only in `editing.js` and which no C++ path knew about. Every exception states its code in its declaration through `CodedException`, so `error_code()` recovers it from any `std::exception` and no binding needs a ladder. The head keeps the order `ODRError` shipped, so no value an installed iOS app reads moves; the refusals move onto the band from 1001. `html/frontend.cpp::write_error_codes` writes that band into every document view as `odr.errorCodes`, always inline, so the scripts hold the wording and not the numbers. `test/browser/serve.py` builds the same table out of the header rather than being a fourth copy of it. BREAKING CHANGE: the codes the page reports through `odr.onError` and `odr.onEditRefused` moved from 1 to 9 onto 1001 to 1009. `readOnly` is 1005, not 5. The `reason` string on the event is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SV2gW7QGeAEyuZLbzATDGH
andiwand
force-pushed
the
feat/one-error-code-space
branch
from
September 10, 2026 19:29
2fa28b4 to
3093aca
Compare
andiwand
enabled auto-merge (squash)
September 10, 2026 19:30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 Generated with Claude Code
Why
The same fifteen exception kinds were written out by hand in five places, and nothing could check that the five agreed:
jni/src/odr_jni.cppthrow_javaapple/src/ODRInternal.mmerror_code()ODRErrorapple/…/ODRError.hNS_ERROR_ENUM, values 1…15wasm/src/odr_wasm.cpppython/src/bind_core.cppregister_exceptioncallsSeparately, the codes the rendered page reports for a refused edit lived only in
editing.js— 1 to 8 in a literal table, plus a code 9 that had no entry at all, only the comment "holds 9". The apps then mapped those numbers a third time, in Kotlin and Swift.docs/design/spreadsheet-editing.mdcalled code 1errorIllegalEditNewLine; the code called itnewLine. The doc and the code had already parted.What
odr::ErrorCode(src/odr/error_code.hpp) — one banded number space:ODRErroralready ships, so no value an installed iOS app reads moves.Every exception states its code in its declaration by deriving from
CodedException<ErrorCode::…>, so there is no per-type boilerplate.odr::error_code()recovers it from anystd::exception, and all four catch ladders are gone:odr_jni.cpperror_code_name, base class as fallback;OdrException.getCode()carries the numberODRInternal.mmstatic_assertsodr_wasm.cppcatch; the envelope gainscodebesidetypebind_core.cppodr.ErrorCodederived from the tableenumTables()ErrorCodederived alongsideFileTypeThe page reads the numbers from C++.
frontend.cpp::write_error_codeswrites the editing band into every document view asodr.errorCodes, always inline so it also works when the config links the scripts as shipped resources.editing.jskeeps the wording — it is for a console, and nothing here is localised — and holds no number.document.js's literal9becameunnameableEdit, which now has a name and a message it never had.test/browser/serve.pysynthesises the same table fromerror_code.{hpp,cpp}, so the check pages are not a fourth copy.Breaking
The page's refusal codes moved from 1…9 to 1001…1009 —
readOnlyis 1005, not 5. A host mapping them by number has to move with them. Thereasonstring on the event is unchanged, so a host matching on that is unaffected.Verification
odr_test: 1695 passed, 6 pre-existing skips.error_code_test.cpppins both bands, checks every declared exception states a code, and that no code or name repeats.-Wall -Wextra -Werrorobject builds of the jni and apple units,emcc -Werror -fsyntax-onlyon the wasm units, pybind syntax check on the python unit. That caughtthrow_newgoing dead, which the default local build does not.cd84aae/f3603a2.