Keep using Photos.app like you always do. Attic quietly backs up your originals and edits to an S3 bucket you control. One-way, append-only.
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix RetryPolicyTests to use typed S3ClientError for transient errors

+8 -8
+8 -8
Tests/AtticCoreTests/RetryPolicyTests.swift
··· 12 12 let counter = Counter() 13 13 let result: String = try await withRetry(baseDelay: .milliseconds(10)) { 14 14 let attempt = await counter.increment() 15 - if attempt == 1 { throw TransientError("fetch failed") } 15 + if attempt == 1 { throw TransientError.make("fetch failed") } 16 16 return "ok" 17 17 } 18 18 #expect(result == "ok") ··· 40 40 baseDelay: .milliseconds(10), 41 41 ) { 42 42 await counter.increment() 43 - throw TransientError("ECONNRESET") 43 + throw TransientError.make("ECONNRESET") 44 44 } 45 45 } catch { 46 - #expect(error is TransientError) 46 + #expect(error is S3ClientError) 47 47 } 48 48 #expect(await counter.value == 3) 49 49 } ··· 56 56 baseDelay: .milliseconds(100), 57 57 ) { 58 58 await counter.increment() 59 - throw TransientError("timeout") 59 + throw TransientError.make("timeout") 60 60 } as Int 61 61 } 62 62 ··· 76 76 77 77 // MARK: - Test helpers 78 78 79 - private struct TransientError: Error, CustomStringConvertible { 80 - let description: String 81 - init(_ description: String) { 82 - self.description = description 79 + /// Simulates a transient server error that isTransient() recognizes. 80 + private enum TransientError { 81 + static func make(_ message: String) -> Error { 82 + S3ClientError.httpError(503, message) 83 83 } 84 84 } 85 85