Repository navigation
fix(mobile): preserve drafts after storage read failures - #213
Conversation
A failed mobile draft or outbox read looked like an empty store. The next save could overwrite saved work, and environment cleanup could drop queued messages it could not list. Draft saves now require successful hydration. Outbox loads no longer return a partial queue. Removing an environment stops if its outbox cannot be read. In-flight send failures retry by error tag, including RpcClientError socket reads whose message is only "An error occurred during Read". Adapted from T3 Code pingdotgg#9710 and pingdotgg#10245. Akeru has no hosted cloud draft archive, so this keeps the local fail-closed behavior only. Created with Grok 4.6 High in Grok Build via Orca.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR strengthens mobile draft and outbox persistence around incomplete storage reads and in-flight writes. Readable queued messages can hydrate while incomplete records remain visible for safe cleanup, connected sessions retry incomplete hydration for a bounded window, and final draft flushes include edits queued during earlier persistence work. Confidence Score: 5/5Safe to merge; there are no outstanding blocking issues. No new findings remain. The corrupt-record hydration concern was withdrawn after greptile-apps[bot] accepted the documented fail-closed cleanup rationale. PRRT_kwDOUFhSmc6hMaI0 was manually resolved by leoisadev1 without explanation. PRRT_kwDOUFhSmc6hMx_W was manually resolved by leoisadev1 without explanation. PRRT_kwDOUFhSmc6h8H9o was manually resolved by leoisadev1 without explanation. PRRT_kwDOUFhSmc6h8H9v was manually resolved by leoisadev1 without explanation. Reviews (6): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile |
A mixed outbox with one unreadable record rejected the whole load, so valid queued messages never reached delivery after restart. Load now returns the readable messages and keeps unread files on disk with diagnostics. Environment cleanup still stops when any record cannot be read, so attachment owners from unread files are not deleted. Created with Grok 4.6 High in Grok Build via Orca.
A valid pending-task file next to a corrupt sibling hydrates into the same queue atom the drain and pending-task list read. The unread file stays on disk, and environment cleanup still refuses to delete unknown attachment owners. Created with Grok 4.6 High in Grok Build via Orca.
|
This is Leo's agent. The earlier reply on
Evidence from Remaining limitation: a permanently corrupt file has no in-app discard UI. It stays on disk and blocks environment removal until it can be decoded. Readable queued work still sends. |
A mixed load published readable messages, then cached that result. A sibling file that became readable later never joined the drain queue until JS restarted. Incomplete loads now drop the cache, and drain asks for another read on reconnect. Created with Grok 4.6 High in Grok Build via Orca.
Problem
A failed mobile draft read could look like an empty store. The next save could overwrite saved work. An unreadable outbox record previously rejected the whole queue, so valid queued messages never reached delivery after restart. A send that failed in flight after reconnect was treated as a deterministic rejection because
SocketReadErroronly says"An error occurred during Read". The drain then restored the queued text into a draft and deleted the outbox entry.Changes
Draft saves now require successful hydration. Final flush retries pending edits after a successful read.
Outbox load returns readable queued messages and leaves unreadable files on disk with diagnostics. Hydration publishes those readable messages so they can send after reconnect. Environment cleanup still stops if any outbox record cannot be read, so unread attachment owners are not deleted.
Queued delivery classifies failures by error tag first:
OrchestrationDispatchCommandError,EnvironmentAuthorizationErrorConnectionTransientError,RpcClientError(any socket reason or protocol defect),EnvironmentRpcUnavailableError,EnvironmentNotRegisteredErrorUntagged errors still fall back to the message matcher.
Adaptation
Reviewed ports of T3 Code #9710 and T3 Code #10245. Akeru has no hosted cloud draft archive or file-backed attachment cleanup yet, so this keeps local draft fail-closed behavior and tagged retry classification. Outbox hydration recovers readable records instead of blocking the whole queue on one unread file.
Scope
Mobile draft persistence, thread outbox load/cleanup, and send-failure classification. No web UI, native modules, providers, or contracts.
Verification
vp test run apps/mobile/src/state/use-composer-drafts.test.ts apps/mobile/src/state/thread-outbox.test.ts— 45 passed (28 outbox), including mixed valid/corrupt files through expo storage plus the drain/pending-task atom, cleanup that still stops on unread records, draft read/decode preservation, flush retry, and tagged transport retriesvp linton the touched files — 0 warnings, 0 errorsvp run --filter @t3tools/mobile typecheck— passedThis is persistence and classification logic. No rendered web or desktop UI change. Native Android/iOS device runs are blocked on this Linux host: no
adb, Android SDK, or Xcode. Unit tests use temporary-file mocks and cover the real-source failure cases.Limitations
Created with Grok 4.6 High in Grok Build via Orca.