File tree Expand file tree Collapse file tree 3 files changed +75
-1
lines changed
Expand file tree Collapse file tree 3 files changed +75
-1
lines changed Original file line number Diff line number Diff line change @@ -168,7 +168,7 @@ public enum ErrorKit {
168168 } else {
169169 // For enums, include the full case description with type name
170170 if let enclosingType {
171- return " \( enclosingType) . \( error) "
171+ return " \( enclosingType) . \( String ( describing : error) ) "
172172 } else {
173173 return String ( describing: error)
174174 }
Original file line number Diff line number Diff line change @@ -17,3 +17,38 @@ extension String {
1717 }
1818 #endif
1919}
20+
21+ extension String . StringInterpolation {
22+ /// Interpolates an error using its user-friendly message.
23+ ///
24+ /// Uses ``ErrorKit.userFriendlyMessage(for:)`` to provide clear, actionable error descriptions
25+ /// suitable for displaying to users. For nested errors, returns the message from the root cause.
26+ ///
27+ /// ```swift
28+ /// showAlert("Operation failed: \(error)")
29+ /// ```
30+ ///
31+ /// - Parameter error: The error to interpolate using its user-friendly message
32+ mutating public func appendInterpolation( _ error: some Error ) {
33+ self . appendInterpolation ( ErrorKit . userFriendlyMessage ( for: error) )
34+ }
35+
36+ /// Interpolates an error using its complete chain description for debugging.
37+ ///
38+ /// Uses ``ErrorKit.errorChainDescription(for:)`` to show the full error hierarchy,
39+ /// type information, and nested structure. Ideal for logging and debugging.
40+ ///
41+ /// ```swift
42+ /// Logger().error("Operation failed with:\n\(chain: error)")
43+ /// // Operation failed with:
44+ /// // DatabaseError
45+ /// // └─ FileError
46+ /// // └─ PermissionError.denied(permission: "~/Downloads/Profile.png")
47+ /// // └─ userFriendlyMessage: "Access to ~/Downloads/Profile.png was declined..."
48+ /// ```
49+ ///
50+ /// - Parameter error: The error to interpolate using its complete chain description
51+ mutating public func appendInterpolation( chain error: some Error ) {
52+ self . appendInterpolation ( ErrorKit . errorChainDescription ( for: error) )
53+ }
54+ }
Original file line number Diff line number Diff line change @@ -40,6 +40,45 @@ enum ErrorKitTests {
4040 }
4141 }
4242
43+ enum StringInterpolation {
44+ @Test
45+ static func implicitWithStruct( ) async throws {
46+ #expect( " \( SomeThrowable ( ) ) " == " Something failed hard. " )
47+ }
48+
49+ @Test
50+ static func implicitWithNestedError( ) async throws {
51+ let nestedError = DatabaseError . caught ( FileError . caught ( PermissionError . denied ( permission: " ~/Downloads/Profile.png " ) ) )
52+ #expect( " \( nestedError) " == " Access to ~/Downloads/Profile.png was declined. To use this feature, please enable the permission in your device Settings. " )
53+ }
54+
55+ @Test
56+ static func chainWithStruct( ) async throws {
57+ #expect(
58+ " \( chain: SomeThrowable ( ) ) "
59+ ==
60+ """
61+ SomeThrowable [Struct]
62+ └─ userFriendlyMessage: " Something failed hard. "
63+ """
64+ )
65+ }
66+
67+ @Test
68+ static func chainWithNestedError( ) async throws {
69+ let nestedError = DatabaseError . caught ( FileError . caught ( PermissionError . denied ( permission: " ~/Downloads/Profile.png " ) ) )
70+ #expect(
71+ " \( chain: nestedError) "
72+ ==
73+ """
74+ DatabaseError
75+ └─ FileError
76+ └─ PermissionError.denied(permission: " ~/Downloads/Profile.png " )
77+ └─ userFriendlyMessage: " Access to ~/Downloads/Profile.png was declined. To use this feature, please enable the permission in your device Settings. "
78+ """ )
79+ }
80+ }
81+
4382 enum ErrorChainDescription {
4483 @Test
4584 static func localizedError( ) {
You can’t perform that action at this time.
0 commit comments