You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 4268a54
Browse filesBrowse the repository at this point in the historyBrowse files
- EventSeats rejects a capacity that is not a whole, non-negative number
with invalid_capacity, and hold stops at available <= 0. A capacity of
1.5 let holds drive availability below zero.
- The sync route answers 422 for UnknownOperation, so a device stops
retrying a queued write for an operation that a server deploy removed.
- The SQL room store uses a RoomState type and guards the stored JSON;
loadRoom throws for an unexpected shape instead of returning it.
- The cross-process race test kills its child process after each test,
so a failed run leaves no waiting process.
Each fix started from a failing test. The guides embed the new example
files and describe the new behavior.
if (error instanceof InvalidPayload || error instanceof IdempotencyConflict) {
213
+
if (
214
+
error instanceof InvalidPayload ||
215
+
error instanceof IdempotencyConflict ||
216
+
error instanceof UnknownOperation
217
+
) {
213
218
returnnewResponse(null, { status:422 })
214
219
}
215
220
throw error
@@ -223,7 +228,7 @@ Delivery through `receiveTransmitEnvelope` skips `authorizeMessage`. The route m
223
228
224
229
The example gives those checks to `canWrite`. If that callback denies the request, the route answers 403 and does not enqueue the write. The browser policy cannot replace these server checks.
225
230
226
-
The route answers 422 for `InvalidPayload`and `IdempotencyConflict`. The browser converts that response to `NonRetryableError` and stops retries for that write. This response prevents repeated attempts for an envelope that cannot apply.
231
+
The route answers 422 for `InvalidPayload`, `IdempotencyConflict`, and `UnknownOperation`. An `UnknownOperation` occurs when a device queued a write for an operation that a later server deploy removed. The browser converts that response to `NonRetryableError` and stops retries for that write. This response prevents repeated attempts for an envelope that cannot apply.
227
232
228
233
A Rails server can receive the same envelopes with `SolidObjects::Transmission.receive`. That method also skips message authorization. Authenticate the device before the call. Check its permission to write the actor.
229
234
@@ -265,6 +270,7 @@ The [route tests](../../test/guide-offline-first.test.ts) check these cases:
265
270
- An authorized request receives 200 and adds the expected finding.
266
271
- A repeated envelope receives 200 and leaves one finding.
267
272
- An envelope with an empty operation receives 422.
273
+
- An envelope for an operation that the server removed receives 422.
268
274
269
275
These tests do not check every browser engine or every interruption during delivery. They also do not test `IdempotencyConflict` or the browser response to 422.
The SQL design stores each room as JSON in a row with a `version` column and a turn deadline. `loadRoom` returns the state and its version. The caller passes that version to `saveRoom` as `expectedVersion`.
143
+
The SQL design stores each room as JSON in a row with a `version` column and a turn deadline. `loadRoom` returns the state and its version. It checks the stored JSON against `RoomState` and throws when the shape is unexpected, so the caller never uses unchecked data. The caller passes that version to `saveRoom` as `expectedVersion`.
133
144
134
145
`saveRoom` updates a row only when its version still matches. A successful update also increases the version. A write from an old version returns `{ saved: false }`. The caller then reloads the room and tries again. An old copy of the state cannot replace a newer copy.
135
146
@@ -356,7 +367,7 @@ In tests, `runtime.testing.runDueReminders({ now })` finds due reminders at the
356
367
The [tests for persistent rooms](../../test/guide-persistent-rooms.test.ts) check these cases in this order:
357
368
358
369
1. A new instance of the memory design has no room and no timer after a simulated restart.
359
-
2. The SQL room survives a database reopen. A write from an old version fails, and the sweep finds the due room.
370
+
2. The SQL room survives a database reopen. A write from an old version fails, and the sweep finds the due room. A stored room with an unexpected shape fails to load.
360
371
3. Two submissions for one turn produce one accepted move and one `stale_turn` rejection.
361
372
4. A move from the wrong player rejects with `not_your_turn`.
362
373
5. A caller cannot submit a move for another player.
@@ -252,7 +255,7 @@ Calls for one event run one at a time, in order, across processes. Different eve
252
255
253
256
An old form can overwrite newer data even when calls run in order. The calls run in order, but the second call still carries old data. The actor needs a rule that detects this conflict.
254
257
255
-
`setCapacity` takes `expectedRevision` and compares it with `revision`. A mismatch rejects the change with `stale_revision`. An accepted capacity change increases the revision.
258
+
`setCapacity` takes `expectedRevision` and compares it with `revision`. A mismatch rejects the change with `stale_revision`. An accepted capacity change increases the revision. A capacity that is not a whole, non-negative number rejects with `invalid_capacity`, so a fractional capacity cannot leave a part of a seat to hold.
256
259
257
260
The test accepts a change from 10 seats to 12 seats. An old form then requests eight seats with the previous revision. The actor rejects that request and keeps the capacity at 12.
258
261
@@ -337,6 +340,7 @@ The [test file](../../test/guide-race-conditions.test.ts) checks these outcomes:
337
340
- A late expiry after a confirmation changes nothing.
338
341
- A confirmation after expiry rejects with `hold_expired`.
339
342
- A capacity change from a stale form rejects with `stale_revision`.
343
+
- A fractional or negative capacity rejects with `invalid_capacity`.
340
344
- A buyer cannot change capacity.
341
345
342
346
The assertions check both results and stored state. They show the behavior of these examples and their conflict cases.
0 commit comments