Skip to content

Docs: error handling, configuration, records, and limits articles#362

Closed
leogdion wants to merge 2 commits into
v1.0.0-beta.2from
361-docs-error-config-records
Closed

Docs: error handling, configuration, records, and limits articles#362
leogdion wants to merge 2 commits into
v1.0.0-beta.2from
361-docs-error-config-records

Conversation

@leogdion

Copy link
Copy Markdown
Member

Summary

Adds four DocC articles to close out the open documentation gaps tracked by parent #361:

  • HandlingErrors.md — three-layer error model (construction, token, request) with retry/recovery guidance. Covers CloudKitError, TokenManagerError, TokenStorageError, CredentialsValidationError, and the four *Reason enums.
  • ConfiguringMistKit.md — container, environment, transport, and logging inputs. Explicitly defers credential construction to AuthenticationAndDatabases.md to avoid duplication. Notes there is no MistKitConfiguration type (issue Add comprehensive configuration documentation #116's terminology) — configuration is what you pass to CloudKitService.init.
  • WorkingWithRecords.md — CRUD, batched modifyRecords, lookup, and sync-via-change-token walks.
  • CloudKitLimitsAndPerformance.md — pagination guard (maxPages: 1_000 + stuck-marker detection), batch sizing, asset upload transport split (URLSession.shared vs configured ClientTransport, with the 421 Misdirected Request rationale), CloudKit rate limits.

Also adds inline # Example blocks to modifyRecords, createRecord, updateRecord, deleteRecord (CloudKitService+WriteOperations.swift) and lookupRecords (CloudKitService+LookupOperations.swift) to match the existing example style on queryRecords.

Updates Documentation.md Topics:

  • Adds the three new article links plus <doc:HandlingErrors> under Getting Started / Error Handling.
  • Adds a new ### Error Handling group covering the typed error and reason enums.

Out of scope (deliberate)

Test plan

  • swift build — DocC catalog parses, articles compile
  • swift test — 454 tests pass; no regressions from inline doc edits
  • ./Scripts/lint.sh — swift-format, swiftlint (0 violations across 300 files), periphery (no unused code) all clean
  • CI DocC build step verifies <doc:> cross-links and Type references resolve

Closes #115
Closes #116
Closes #160

🤖 Generated with Claude Code

leogdion and others added 2 commits May 18, 2026 14:47
#334)

Resolves the two open sub-issues under #359.

#159 — Every import in Sources/MistKit, Tests, and the three Examples
packages (MistDemo, BushelCloud, CelestraCloud) now carries an explicit
access modifier. Default is `internal import`; pre-existing `public import`
lines (for modules whose types appear in public API signatures) are
preserved. `@testable import` is untouched. Sources/MistKitOpenAPI is
generated and excluded; its one remaining bare `import HTTPTypes` is
tracked in follow-up #360.

#334 — Adds `TestPlatform.isFlakyTimeoutSimulator` (visionOS / watchOS
simulator AND `CI` env) and a `withKnownIssue(when:isIntermittent:_:)`
overload. The six previously-blanket `withKnownIssue(isIntermittent: true)`
gates in the withTimeout / withTimeoutAndSignals tests now pass
`when: TestPlatform.isFlakyTimeoutSimulator`, so the intermittent
allowance applies only on the flaky CI sim runs while every other
platform (macOS host, Linux, iOS device, local sim runs) asserts strictly
and surfaces real regressions.

CLAUDE.md gains an "Import Conventions" section documenting the new
rule and the MistKitOpenAPI carve-out.

Verified: swift build + swift test green at repo root and each Examples
package (454 + 930 + 220 + 115 tests); mise exec -- swiftlint clean;
Scripts/lint.sh (build + lint + headers + periphery) clean.

Closes #159
Closes #334
Closes #359

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds four DocC articles to close out the open documentation gaps
tracked by parent issue #361:

- HandlingErrors.md — three-layer error model (construction, token,
  request) with retry/recovery guidance.
- ConfiguringMistKit.md — container/environment/transport/logging
  inputs; defers credential construction to AuthenticationAndDatabases.
- WorkingWithRecords.md — CRUD, batch, lookup, and sync-via-token walks.
- CloudKitLimitsAndPerformance.md — pagination guard, batch sizing,
  asset upload transport split, rate limits.

Also adds inline `# Example` blocks to modifyRecords, createRecord,
updateRecord, deleteRecord (CloudKitService+WriteOperations.swift) and
lookupRecords (CloudKitService+LookupOperations.swift) to match the
existing example style on queryRecords. Updates Documentation.md Topics
to surface the new articles and adds an Error Handling group covering
the typed error and reason enums.

Migration guide (mentioned in #160) is deferred — MistKit is at
1.0.0-beta.1 with no stable predecessor; that article should land
alongside a future release transition.

Closes #115
Closes #116
Closes #160

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 300 files, which is 150 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5472a672-71dc-443d-9d4f-5fe2f18cac4f

📥 Commits

Reviewing files that changed from the base of the PR and between d11c6c5 and 14395bb.

📒 Files selected for processing (300)
  • CLAUDE.md
  • Examples/BushelCloud/Sources/BushelCloudCLI/BushelCloudCLI.swift
  • Examples/BushelCloud/Sources/BushelCloudCLI/Commands/ClearCommand.swift
  • Examples/BushelCloud/Sources/BushelCloudCLI/Commands/ExportCommand.swift
  • Examples/BushelCloud/Sources/BushelCloudCLI/Commands/ListCommand.swift
  • Examples/BushelCloud/Sources/BushelCloudCLI/Commands/StatusCommand.swift
  • Examples/BushelCloud/Sources/BushelCloudCLI/Commands/SyncCommand.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/CloudKit/BushelCloudKitService.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/CloudKit/CloudKitAuthMethod.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/CloudKit/KeyIDValidator.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/CloudKit/OperationClassification.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/CloudKit/PEMValidator.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/CloudKit/SyncEngine+Export.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/CloudKit/SyncEngine.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/Configuration/BushelConfiguration.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/Configuration/CloudKitConfiguration.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/Configuration/CommandConfigurations.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/Configuration/ConfigurationKeys.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/Configuration/ConfigurationLoader+Loading.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/Configuration/ConfigurationLoader.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/AppleDBEntry.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/AppleDBFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/AppleDBHashes.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/AppleDBLink.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/AppleDBSource.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/GitHubCommit.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/GitHubCommitsResponse.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/GitHubCommitter.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/AppleDB/SignedStatus.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/DataSourcePipeline+Deduplication.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/DataSourcePipeline+Fetchers.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/DataSourcePipeline+ReferenceResolution.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/DataSourcePipeline.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/IPSWFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/MESUFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/MrMacintoshFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/SwiftVersionFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/TheAppleWiki/IPSWParser.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/TheAppleWiki/Models/IPSWVersion.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/TheAppleWiki/Models/ParseContent.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/TheAppleWiki/Models/ParseResponse.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/TheAppleWiki/Models/TextContent.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/TheAppleWiki/TheAppleWikiFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/VirtualBuddyFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/DataSources/XcodeReleasesFetcher.swift
  • Examples/BushelCloud/Sources/BushelCloudKit/Utilities/ConsoleOutput.swift
  • Examples/BushelCloud/Sources/ConfigKeyKit/ConfigKey.swift
  • Examples/BushelCloud/Sources/ConfigKeyKit/ConfigurationKey.swift
  • Examples/BushelCloud/Sources/ConfigKeyKit/OptionalConfigKey.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/CloudKit/MockCloudKitServiceTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/CloudKit/PEMValidatorTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Configuration/ConfigurationLoaderTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Configuration/FetchConfigurationTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/MockAppleDBFetcherTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/MockIPSWFetcherTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/MockMESUFetcherTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/MockSwiftVersionFetcherTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/MockXcodeReleasesFetcherTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/RestoreImageDeduplicationTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/RestoreImageMergeTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/SwiftVersionDeduplicationTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/VirtualBuddyFetcherTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/XcodeVersionDeduplicationTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/DataSources/XcodeVersionReferenceResolutionTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/ErrorHandling/AuthenticationErrorHandlingTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/ErrorHandling/CloudKitErrorHandlingTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/ErrorHandling/GracefulDegradationTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/ErrorHandling/NetworkErrorHandlingTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Extensions/FieldValueURLTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockAppleDBFetcher.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockCloudKitService.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockFetcherError.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockIPSWFetcher.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockMESUFetcher.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockSwiftVersionFetcher.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockURLProtocol.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Mocks/MockXcodeReleasesFetcher.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Models/DataSourceMetadataTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Models/RestoreImageRecordTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Models/SwiftVersionRecordTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Models/XcodeVersionRecordTests.swift
  • Examples/BushelCloud/Tests/BushelCloudKitTests/Utilities/FieldValue+Assertions.swift
  • Examples/BushelCloud/Tests/ConfigKeyKitTests/ConfigKeySourceTests.swift
  • Examples/BushelCloud/Tests/ConfigKeyKitTests/ConfigKeyTests.swift
  • Examples/BushelCloud/Tests/ConfigKeyKitTests/NamingStyleTests.swift
  • Examples/BushelCloud/Tests/ConfigKeyKitTests/OptionalConfigKeyTests.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Celestra.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Commands/AddFeedCommand.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Commands/ClearCommand.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Commands/UpdateCommand+Reporting.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Commands/UpdateCommand.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Commands/UpdateCommandError.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Commands/UpdateSummary.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Services/FeedUpdateProcessor+Fetch.swift
  • Examples/CelestraCloud/Sources/CelestraCloud/Services/FeedUpdateProcessor.swift
  • Examples/CelestraCloud/Sources/CelestraCloudKit/Services/ArticleCloudKitService.swift
  • Examples/CelestraCloud/Sources/CelestraCloudKit/Services/FeedCloudKitService.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Configuration/CloudKitConfigurationTests.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Configuration/UpdateCommandConfigurationTests.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Errors/CelestraErrorTests+Description.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Errors/CelestraErrorTests+RecoverySuggestion.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Errors/CelestraErrorTests.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Errors/CloudKitConversionErrorTests.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Extensions/ArticleConversion+FromCloudKit.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Extensions/ArticleConversion+ToCloudKit.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Extensions/FeedConversion+FromCloudKit.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Extensions/FeedConversion+RoundTrip.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Extensions/FeedConversion+ToCloudKit.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Mocks/MockCloudKitRecordOperator.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Models/BatchOperationResultTests.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/ArticleCategorizer+Advanced.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/ArticleCategorizer+Basic.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/ArticleCloudKitService+Mutations.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/ArticleCloudKitService+Query.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/FeedCloudKitService+CRUD.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/FeedCloudKitService+Query.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/FeedMetadataBuilder+Error.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/FeedMetadataBuilder+NotModified.swift
  • Examples/CelestraCloud/Tests/CelestraCloudTests/Services/FeedMetadataBuilder+Success.swift
  • Examples/MistDemo/App/MistDemoApp.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/Command.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/CommandLineParser.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/CommandRegistry.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/ConfigKey+Bool.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/ConfigKey.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/ConfigurationKey.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/ConfigurationParseable.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/OptionalConfigKey.swift
  • Examples/MistDemo/Sources/ConfigKeyKit/StandardNamingStyle.swift
  • Examples/MistDemo/Sources/MistDemo/MistDemo.swift
  • Examples/MistDemo/Sources/MistDemoApp/Models/CKRecord+TypedField.swift
  • Examples/MistDemo/Sources/MistDemoApp/Models/Note.swift
  • Examples/MistDemo/Sources/MistDemoApp/Models/ZoneRow.swift
  • Examples/MistDemo/Sources/MistDemoApp/Services/CKDatabase+WebAuthToken.swift
  • Examples/MistDemo/Sources/MistDemoApp/Services/CKDatabase.Scope+Demo.swift
  • Examples/MistDemo/Sources/MistDemoApp/Services/CloudKitStore.swift
  • Examples/MistDemo/Sources/MistDemoApp/Services/CloudKitStoreError.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/AccountView+Actions.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/AccountView.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/DetailColumnRoot.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/NoteEditView.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/QueryView.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/RecordDetailView.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/SidebarView.swift
  • Examples/MistDemo/Sources/MistDemoApp/Views/ZoneListView.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/CreateCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/CurrentUserCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/DeleteCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/DeleteResult.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/DemoErrorsCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/DemoErrorsRunner+Output.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/DemoErrorsRunner.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/DemoInFilterCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/FetchChangesCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/LookupCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/LookupZonesCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/MistDemoCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/ModifyCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/ModifyOutput.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/ModifyResultRow.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/QueryCommand+FilterParsing.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/QueryCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/TestPrivateCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/TestPublicCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/UpdateCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Commands/UploadAssetCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/AuthTokenConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/BrowserFlagResolver.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/ConfigurationError.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/CreateConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/CurrentUserConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/DeleteConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/DemoErrorsConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/DemoErrorsError.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/Field.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/FieldType.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/LookupConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/LookupZonesConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/MistDemoConfig+Parsing.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/MistDemoConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/MistDemoConfiguration.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/QueryConfig+Parsing.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/QueryConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/TestPrivateConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/UpdateConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/UploadAssetConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Configuration/WebConfig.swift
  • Examples/MistDemo/Sources/MistDemoKit/Constants/MistDemoConstants+Defaults.swift
  • Examples/MistDemo/Sources/MistDemoKit/Constants/MistDemoConstants+Messages.swift
  • Examples/MistDemo/Sources/MistDemoKit/Constants/MistDemoConstants.swift
  • Examples/MistDemo/Sources/MistDemoKit/Errors/ErrorOutput+Convenience.swift
  • Examples/MistDemo/Sources/MistDemoKit/Errors/ErrorOutput.swift
  • Examples/MistDemo/Sources/MistDemoKit/Errors/FieldConversionError.swift
  • Examples/MistDemo/Sources/MistDemoKit/Errors/MistDemoError.swift
  • Examples/MistDemo/Sources/MistDemoKit/Extensions/Array+Field.swift
  • Examples/MistDemo/Sources/MistDemoKit/Extensions/Command+AnyCommand.swift
  • Examples/MistDemo/Sources/MistDemoKit/Extensions/ConfigKey+MistDemo.swift
  • Examples/MistDemo/Sources/MistDemoKit/Extensions/FieldValue+FieldType.swift
  • Examples/MistDemo/Sources/MistDemoKit/Extensions/String+Padding.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/AssetUploadReceipt+PhaseState.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/CleanupPhaseMarker.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/CreatedRecordNames.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/IncrementalSyncInput.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/IntegrationPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/IntegrationTest.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/IntegrationTestData.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/IntegrationTestError.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/IntegrationTestRunner.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/NoState.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/PhaseContext.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/PhaseState.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/PhaseStateDecodable.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/PhaseStateEncodable.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/PhasedIntegrationTest.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/CleanupPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/CreateRecordsPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/DiscoverUserIdentitiesPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/FetchCallerPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/FetchZoneChangesPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/FinalVerificationPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/IncrementalSyncPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/InitialSyncPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/ListZonesPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/LookupRecordsPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/LookupUsersByEmailPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/LookupUsersByRecordNamePhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/LookupZonePhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/ModifyRecordsPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/QueryRecordsPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Phases/UploadAssetPhase.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/SyncTokenSlot.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Tests/PrivateDatabaseTest.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/Tests/PublicDatabaseTest.swift
  • Examples/MistDemo/Sources/MistDemoKit/Integration/UserInfo+PhaseState.swift
  • Examples/MistDemo/Sources/MistDemoKit/MistDemoRunner.swift
  • Examples/MistDemo/Sources/MistDemoKit/Models/AuthRequest.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Escapers/CSVEscaper.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Escapers/JSONEscaper.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Escapers/OutputEscaperFactory.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Escapers/TableEscaper.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Escapers/YAMLEscaper.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Formatters/CSVFormatter.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Formatters/OutputFormatterFactory.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Formatters/TableFormatter.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Formatters/YAMLFormatter.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/JSONFormatter.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/OutputFormat.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/OutputFormatter.swift
  • Examples/MistDemo/Sources/MistDemoKit/Output/Protocols/OutputEscaper.swift
  • Examples/MistDemo/Sources/MistDemoKit/Protocols/OutputFormatting+Implementations.swift
  • Examples/MistDemo/Sources/MistDemoKit/Protocols/OutputFormatting+Records.swift
  • Examples/MistDemo/Sources/MistDemoKit/Protocols/OutputFormatting+Users.swift
  • Examples/MistDemo/Sources/MistDemoKit/Protocols/OutputFormatting.swift
  • Examples/MistDemo/Sources/MistDemoKit/Types/AnyCodable.swift
  • Examples/MistDemo/Sources/MistDemoKit/Types/DynamicKey.swift
  • Examples/MistDemo/Sources/MistDemoKit/Types/FieldInputValue.swift
  • Examples/MistDemo/Sources/MistDemoKit/Types/FieldsInput.swift
  • Examples/MistDemo/Sources/MistDemoKit/Utilities/AsyncHelpers.swift
  • Examples/MistDemo/Sources/MistDemoKit/Utilities/AuthenticationError.swift
  • Examples/MistDemo/Sources/MistDemoKit/Utilities/AuthenticationHelper+SetupHelpers.swift
  • Examples/MistDemo/Sources/MistDemoKit/Utilities/AuthenticationHelper.swift
  • Examples/MistDemo/Sources/MistDemoKit/Utilities/AuthenticationResult.swift
  • Examples/MistDemo/Sources/MistDemoKit/Utilities/BrowserOpener.swift
  • Examples/MistDemo/Sources/MistDemoKit/Utilities/FieldValueFormatter.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+APITokenOnly.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+BadCredentials.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+ContainerIdentifier.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+CustomTokenManager.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+Environment.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+ErrorCases.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+Helpers.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+PrivateKeyFile.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+PublicDatabase.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+ServerToServerAuth.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests+WebAuthToken.swift
  • Examples/MistDemo/Tests/MistDemoTests/CloudKit/MistKitClientFactory/MistKitClientFactoryTests.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/AuthTokenCommand/AuthTokenCommandTests+AsyncChannel.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/AuthTokenCommand/AuthTokenCommandTests+CommandInitialization.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/AuthTokenCommand/AuthTokenCommandTests+Configuration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/AuthTokenCommand/AuthTokenCommandTests+Error.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/AuthTokenCommand/AuthTokenCommandTests+MockServer.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/AuthTokenCommand/AuthTokenCommandTests+Timeout.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/AuthTokenCommand/AuthTokenCommandTests.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests+AuthTokenCommandIntegration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests+CreateCommandIntegration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests+CrossCommandIntegration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests+CurrentUserCommandIntegration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests+ErrorHandlingIntegration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests+QueryCommandIntegration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests+RealWorldUsageSimulation.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CommandIntegration/CommandIntegrationTests.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+CommandProperty.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+Configuration.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+ErrorHandling.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+FieldParsing.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+FieldType.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+FieldTypeConversion.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+FieldValidation.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+GenerateRecordName.swift
  • Examples/MistDemo/Tests/MistDemoTests/Commands/CreateCommand/CreateCommandTests+JSONFieldLoading.swift

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 361-docs-error-config-records

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (v1.0.0-beta.2@1d1f63a). Learn more about missing BASE report.

Additional details and impacted files
@@               Coverage Diff                @@
##             v1.0.0-beta.2     #362   +/-   ##
================================================
  Coverage                 ?   68.91%           
================================================
  Files                    ?      111           
  Lines                    ?     2641           
  Branches                 ?        0           
================================================
  Hits                     ?     1820           
  Misses                   ?      821           
  Partials                 ?        0           
Flag Coverage Δ
mistdemo-spm-macos 11.81% <ø> (?)
mistdemo-swift-6.2-jammy 12.00% <ø> (?)
mistdemo-swift-6.2-noble 11.81% <ø> (?)
mistdemo-swift-6.3-jammy 11.81% <ø> (?)
mistdemo-swift-6.3-noble 11.81% <ø> (?)
spm 67.20% <ø> (?)
swift-6.1-jammy 67.28% <ø> (?)
swift-6.1-noble 67.28% <ø> (?)
swift-6.2-jammy 67.36% <ø> (?)
swift-6.2-noble 67.43% <ø> (?)
swift-6.3-jammy 67.47% <ø> (?)
swift-6.3-noble 67.39% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@leogdion leogdion changed the base branch from main to v1.0.0-beta.2 May 18, 2026 14:11
@claude

claude Bot commented May 18, 2026

Copy link
Copy Markdown

Code Review — PR #362: Docs: error handling, configuration, records, and limits articles

Overall the four articles are well-structured, accurate in the majority of their content, and meaningfully close the gaps from #361. The inline # Example blocks in the Swift source files match the prose examples in the articles, which is exactly the right approach. A few issues below range from build-breaking to nit.


🔴 Critical

1. Broken DocC symbol link — fetchAllRecordChanges(recordType:syncToken:) doesn't exist

WorkingWithRecords.md references this method in both prose (line 142) and the Topics block (line 177):

``CloudKitService/fetchAllRecordChanges(recordType:syncToken:)``

The actual signature (CloudKitService+SyncOperations.swift:166) is:

fetchAllRecordChanges(zoneID:syncToken:resultsLimit:maxPages:database:)

There is no recordType: parameter on this method — that's a query-layer concept, not a changes-feed concept. DocC will fail to resolve this link. The correct reference is:

``CloudKitService/fetchAllRecordChanges(zoneID:syncToken:resultsLimit:maxPages:database:)``

Note: AbstractionLayerArchitecture.md:228 has the same stale reference (fetchAllRecordChanges(recordType:syncToken:)) — that's pre-existing and out of scope here, but worth fixing in a follow-up.


2. Dead catch let error as TokenManagerError — unreachable with typed throws

HandlingErrors.md (lines 52–60) shows:

do {
  _ = try await service.fetchCaller()
} catch let error as TokenManagerError {
  switch error {
  case .tokenExpired:
    try await refreshWebAuthToken()
  ...

Every CloudKitService operation is declared async throws(CloudKitError). Internally, mapToCloudKitError() wraps all errors — including TokenManagerError — into CloudKitError.underlyingError(error) before they escape the method boundary. With typed throws, Swift statically knows only CloudKitError can be thrown, so catch let error as TokenManagerError is dead code and will never execute.

The accurate pattern (if a consumer needs to inspect a TokenManagerError from the auth layer) is:

do {
  _ = try await service.fetchCaller()
} catch CloudKitError.underlyingError(let underlying) {
  if let tokenError = underlying as? TokenManagerError {
    switch tokenError {
    case .tokenExpired:
      try await refreshWebAuthToken()
    default:
      throw CloudKitError.underlyingError(underlying)
    }
  }
} catch {
  throw error
}

The surrounding prose that describes TokenManagerError as "thrown from authentication resolution" is accurate as an implementation description — but readers who copy the catch example verbatim will have a silent no-op branch. The example or the framing should be corrected.


3. Non-compiling retrying helper — uninitialized variable

HandlingErrors.md (lines 139–163) declares:

var lastError: any Error
for attempt in 1...attempts {
  do {
    return try await operation()
  } catch let error as CloudKitError where isTransient(error) {
    lastError = error
    ...
  } catch {
    throw error
  }
}
throw lastError  // ← used before definitely initialized

Swift's definite initialization analysis rejects throw lastError because lastError is only set inside the catch … where isTransient branch — the compiler doesn't know the loop always executes or that the non-transient branch always re-throws before this point. This snippet won't compile.

Fix: initialize to an optional or restructure:

var lastError: (any Error)?
// ...
throw lastError ?? CloudKitError.invalidResponse

🟡 Medium

4. WorkingWithRecords.mdRecordChangesResult in Sync topics is misleading

The Topics block (line 175) lists RecordChangesResult under Sync, which makes sense for fetchRecordChanges. But fetchAllRecordChanges returns (records: [RecordInfo], syncToken: String?) — a tuple, not RecordChangesResult. The article doesn't mention this asymmetry and readers who check the return type of the auto-paginating variant may be confused.


🟢 Positive notes

  • The three-layer error model table in HandlingErrors.md is a great quick-reference. The distinction between construction-time, token-time, and request-time errors is clearly explained.
  • The paginationLimitExceeded carries-partial-results pattern is documented in both articles that touch pagination (HandlingErrors.md and CloudKitLimitsAndPerformance.md), which avoids readers losing data in the error path.
  • The stuck-marker detection behaviour in CloudKitLimitsAndPerformance.md is exactly the right level of detail — it's a non-obvious guarantee and worth surfacing.
  • The 421 Misdirected Request / transport-pool separation rationale in CloudKitLimitsAndPerformance.md is one of the best places in the codebase to have this documented. The custom-transport warning is appropriately prominent.
  • ConfiguringMistKit.md's environment-variable table and env(_:) helper pattern are a nice practical addition that doesn't belong in the API reference but is exactly what a server-side integrator needs.
  • Inline examples in CloudKitService+WriteOperations.swift and CloudKitService+LookupOperations.swift are idiomatic and match the prose in WorkingWithRecords.md.

Summary of required fixes before merge

# File Issue
1 WorkingWithRecords.md:142,177 Fix DocC link to fetchAllRecordChanges(zoneID:syncToken:resultsLimit:maxPages:database:)
2 HandlingErrors.md:52-60 Fix or remove the unreachable catch let error as TokenManagerError example
3 HandlingErrors.md:141 Initialize lastError before use so the snippet compiles

🤖 Generated with Claude Code

@leogdion

Copy link
Copy Markdown
Member Author

Superseded by #364, which keeps CloudKitService+WriteOperations.swift under the file_length cap.

@leogdion leogdion closed this May 18, 2026
@leogdion leogdion deleted the 361-docs-error-config-records branch May 18, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant