refactor(ipc): apply registerCommand wrapper to sync handlers (Phase 2.5) - #242
Merged
Conversation
…2.5)
Migrate 19 schema-input handlers across 4 sync handler files from raw
ipcMain.handle(CH, createValidatedHandler(S, fn)) to the unified
registerCommand(CH, S, fn, fallback) wrapper that composes
createValidatedHandler + withErrorHandler in one call.
Files:
- sync-attachment-handlers.ts: 4 handlers (UPLOAD_ATTACHMENT,
GET_UPLOAD_PROGRESS, DOWNLOAD_ATTACHMENT, GET_DOWNLOAD_PROGRESS)
- auth-oauth-handlers.ts: 3 handlers (AUTH_INIT_OAUTH,
SETUP_FIRST_DEVICE, CONFIRM_RECOVERY_PHRASE)
- auth-device-handlers.ts: 10 handlers (AUTH_REQUEST_OTP,
AUTH_VERIFY_OTP, AUTH_RESEND_OTP, LINK_VIA_QR, COMPLETE_LINKING_QR,
LINK_VIA_RECOVERY, APPROVE_LINKING, GET_LINKING_SAS, REMOVE_DEVICE,
RENAME_DEVICE)
- sync-core-handlers.ts: 2 handlers (GET_HISTORY,
UPDATE_SYNCED_SETTING)
Behavior change: handlers that previously propagated thrown errors to
the renderer as rejected promises (AUTH_INIT_OAUTH, SETUP_FIRST_DEVICE,
LINK_VIA_QR, APPROVE_LINKING, GET_LINKING_SAS, and the OTP trio via
postToServer) now resolve with { success: false, error } envelopes.
Renderer call sites already handle error envelopes via extractErrorMessage
and existing try/catch, so no UI changes needed.
UPDATE_SYNCED_SETTING also gets a typed input
({ fieldPath: string; value: unknown }) in the generated invoke map
instead of `unknown`, a strict improvement over the prior manual
schema.parse call.
Raw ipcMain.handle calls for no-schema channels (SETUP_NEW_ACCOUNT,
GET_RECOVERY_PHRASE, AUTH_REFRESH_TOKEN, AUTH_LOGOUT, GET_DEVICES,
GENERATE_LINKING_QR, GET_STATUS, TRIGGER_SYNC, GET_QUEUE_SIZE, PAUSE,
RESUME, GET_SYNCED_SETTINGS, GET_STORAGE_BREAKDOWN,
GET_QUARANTINED_ITEMS, CHECK_DEVICE_STATUS, EMERGENCY_WIPE) are left
untouched — they have no Zod schema to wrap.
Regenerated generated-ipc-invoke-map.ts via pnpm ipc:generate.
Verification: lint 0 errors, tsc --noEmit -p tsconfig.node.json clean,
24 IPC test files with 300 tests pass, check:architecture pass,
ipc:check pass. No tests required updating.
h4yfans
added a commit
that referenced
this pull request
May 6, 2026
…2.5) (#242) Migrate 19 schema-input handlers across 4 sync handler files from raw ipcMain.handle(CH, createValidatedHandler(S, fn)) to the unified registerCommand(CH, S, fn, fallback) wrapper that composes createValidatedHandler + withErrorHandler in one call. Files: - sync-attachment-handlers.ts: 4 handlers (UPLOAD_ATTACHMENT, GET_UPLOAD_PROGRESS, DOWNLOAD_ATTACHMENT, GET_DOWNLOAD_PROGRESS) - auth-oauth-handlers.ts: 3 handlers (AUTH_INIT_OAUTH, SETUP_FIRST_DEVICE, CONFIRM_RECOVERY_PHRASE) - auth-device-handlers.ts: 10 handlers (AUTH_REQUEST_OTP, AUTH_VERIFY_OTP, AUTH_RESEND_OTP, LINK_VIA_QR, COMPLETE_LINKING_QR, LINK_VIA_RECOVERY, APPROVE_LINKING, GET_LINKING_SAS, REMOVE_DEVICE, RENAME_DEVICE) - sync-core-handlers.ts: 2 handlers (GET_HISTORY, UPDATE_SYNCED_SETTING) Behavior change: handlers that previously propagated thrown errors to the renderer as rejected promises (AUTH_INIT_OAUTH, SETUP_FIRST_DEVICE, LINK_VIA_QR, APPROVE_LINKING, GET_LINKING_SAS, and the OTP trio via postToServer) now resolve with { success: false, error } envelopes. Renderer call sites already handle error envelopes via extractErrorMessage and existing try/catch, so no UI changes needed. UPDATE_SYNCED_SETTING also gets a typed input ({ fieldPath: string; value: unknown }) in the generated invoke map instead of `unknown`, a strict improvement over the prior manual schema.parse call. Raw ipcMain.handle calls for no-schema channels (SETUP_NEW_ACCOUNT, GET_RECOVERY_PHRASE, AUTH_REFRESH_TOKEN, AUTH_LOGOUT, GET_DEVICES, GENERATE_LINKING_QR, GET_STATUS, TRIGGER_SYNC, GET_QUEUE_SIZE, PAUSE, RESUME, GET_SYNCED_SETTINGS, GET_STORAGE_BREAKDOWN, GET_QUARANTINED_ITEMS, CHECK_DEVICE_STATUS, EMERGENCY_WIPE) are left untouched — they have no Zod schema to wrap. Regenerated generated-ipc-invoke-map.ts via pnpm ipc:generate. Verification: lint 0 errors, tsc --noEmit -p tsconfig.node.json clean, 24 IPC test files with 300 tests pass, check:architecture pass, ipc:check pass. No tests required updating.
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.
Summary
Follow-up to PR #241 (Phase 2.1–2.4). Migrates 19 schema-input handlers across the
4 split sync handler files from raw
ipcMain.handle(CH, createValidatedHandler(S, fn))to the unifiedregisterCommand(CH, S, fn, fallback)wrapper introduced in Phase 0.6 (PR #212).registerCommandcomposescreateValidatedHandler+withErrorHandlerin one call,so thrown errors now resolve to
{ success: false, error }envelopes instead ofpropagating as rejected promises. This is the same contract
notes-handlers.tshasbeen on since Phase 0.6, so renderer-side handling already lives alongside both
patterns. The change standardizes on the envelope pattern across the sync IPC
surface.
Scope
UPLOAD_ATTACHMENT,GET_UPLOAD_PROGRESS,DOWNLOAD_ATTACHMENT,GET_DOWNLOAD_PROGRESSAUTH_INIT_OAUTH,SETUP_FIRST_DEVICE,CONFIRM_RECOVERY_PHRASEAUTH_REQUEST_OTP,AUTH_VERIFY_OTP,AUTH_RESEND_OTP,LINK_VIA_QR,COMPLETE_LINKING_QR,LINK_VIA_RECOVERY,APPROVE_LINKING,GET_LINKING_SAS,REMOVE_DEVICE,RENAME_DEVICEGET_HISTORY,UPDATE_SYNCED_SETTINGUntouched (no schema, stay on raw
ipcMain.handle):SETUP_NEW_ACCOUNT,GET_RECOVERY_PHRASE,AUTH_REFRESH_TOKEN,AUTH_LOGOUT,GET_DEVICES,GENERATE_LINKING_QR,GET_STATUS,TRIGGER_SYNC,GET_QUEUE_SIZE,PAUSE,RESUME,GET_SYNCED_SETTINGS,GET_STORAGE_BREAKDOWN,GET_QUARANTINED_ITEMS,CHECK_DEVICE_STATUS,EMERGENCY_WIPE.Incidental improvement
UPDATE_SYNCED_SETTINGpreviously used a manualschema.parse(input)inside a rawipcMain.handlewithinput: unknown. Migrating toregisterCommandgives thegenerated IPC invoke map a properly typed argument signature
(
{ fieldPath: string; value: unknown }instead ofunknown).Test plan
pnpm lint— 0 errors (1435 pre-existing warnings, none new)pnpm --filter @memry/desktop exec tsc --noEmit -p tsconfig.node.json— cleanpnpm --filter @memry/desktop test --run src/main/ipc— 24 files, 300 tests passpnpm check:architecture— passpnpm ipc:check— pass (RPC bindings + invoke map up to date)