feat(loro-websocket): surface JoinError code and appCode on the join rejection - #64
Open
jibize wants to merge 1 commit into
Open
feat(loro-websocket): surface JoinError code and appCode on the join rejection#64jibize wants to merge 1 commit into
jibize wants to merge 1 commit into
Conversation
…rejection
`handleJoinError` rejected with a plain `Error` whose only content was the
formatted string `Join failed: <code> - <message>`, so an application had to
parse that text to tell one refusal from another. The `app_error` (0x7F)
code exists precisely so a server can attach an application-defined
`app_code` (protocol.md: "Extra `varString app_code` (free-form, e.g.,
`quota_exceeded`)"), and the decoder already reads it — but the client
dropped it before the value reached the caller.
Reject with a `JoinFailedError` carrying `code`, `appCode`, `roomId` and
`crdt`. The `message` text is byte-identical to before, so consumers that
still match on the string keep working.
This is the client-side half of the optional hook protocol.md already
describes: `onError({ roomId, kind, code, message, app_code? })`.
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.
Motivation
When a join is refused,
LoroWebsocketClientrejects with a plainErrorwhose only content is the formatted string:That leaves an application no way to tell one refusal from another except by parsing that text. The protocol already anticipates this case —
protocol.mddocuments0x7F app_erroras carrying an extravarString app_code("free-form, e.g.quota_exceeded"), andencoding.tsdecodes it faithfully — but the client discardsappCode(and the numericcode) before the value reaches the caller.protocol.mdalso sketches the hook this closes:Our own use case: our server permanently destroys a room when the underlying record is purged, and refuses any later join for it. Clients must treat that refusal as terminal — evict the local document, stop the reconnect loop — while every other refusal stays retryable. Today we express that by sending
app_errorwith a sentinel message string and substring-matching it on the client, with a comment next to the matcher saying "switch toerr.codewhen the library exposes it". With this change we can send it as anapp_codeand branch on a typed field instead.Scope
One narrow change, in
packages/loro-websocket:JoinFailedError extends Errorcarryingcode,appCode,roomIdandcrdt.handleJoinErrorwith it instead of a bareError.Notes:
appCodewas already on the wire and already decoded. Nothing inrust/needs a counterpart.err.messageis byte-identical to before (Join failed: <code> - <message>), so consumers still matching on the string are unaffected;JoinFailedErroris anError, soinstanceof Errorand existingcatchblocks behave the same.VersionUnknownretry path is untouched.I deliberately left the
onRoomStatusChangelistener signature alone — it already forwards the numericcodeasmessageCode, and widening it to carryappCodefelt like a separate call. Happy to add it here if you'd prefer the two paths to match.Tests
pnpm -r test— one test added inpackages/loro-websocket/src/client/index.test.tsasserting anapp_errorjoin refusal rejects with aJoinFailedErrorexposingcodeandappCode. Full suite green (104 passing).pnpm lintis clean (3 pre-existing warnings, 0 errors) andpackages/loro-websockettypechecks. Two notes on pre-existing state, unrelated to this branch:pnpm typecheckfails inloro-adaptors(src/elo-adaptor.ts, duplicateCryptoKeytypes), andpnpm format:checkis red for 34 files onmain— including both files this PR touches — so I matched the surrounding style rather than reformatting them.Thanks for the protocol and for the work on this repo — happy to adjust the shape of this however you'd like.