Skip to content

Commit 9987568

Browse files
authored
Add an async variant to Catching.catch (#34)
* Add an async variant to Catching.catch * If error caught from catch is already Self, just throw it directly rather than wrapping in a caught enum.
1 parent 2834168 commit 9987568

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

Sources/ErrorKit/Catching.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,55 @@ extension Catching {
135135
) throws(Self) -> ReturnType {
136136
do {
137137
return try operation()
138+
} catch let error as Self {
139+
throw error
140+
} catch {
141+
throw Self.caught(error)
142+
}
143+
}
144+
145+
/// Executes an async throwing operation and automatically wraps any thrown errors into this error type's `caught` case,
146+
/// while passing through the operation's return value on success. Great for functions using typed throws.
147+
///
148+
/// # Overview
149+
/// This function provides a convenient way to:
150+
/// - Execute async throwing operations
151+
/// - Automatically wrap any errors into the current error type
152+
/// - Pass through return values from the wrapped code
153+
/// - Maintain type safety with typed throws
154+
///
155+
/// # Example
156+
/// ```swift
157+
/// struct ProfileRepository {
158+
/// func loadProfile(id: String) throws(ProfileError) {
159+
/// // Regular error throwing for validation
160+
/// guard id.isValidFormat else {
161+
/// throw ProfileError.validationFailed(field: "id")
162+
/// }
163+
///
164+
/// // Automatically wrap any database or file errors while handling return value
165+
/// let userData = try await ProfileError.catch {
166+
/// let user = try await database.loadUser(id)
167+
/// let settings = try await fileSystem.readUserSettings(user.settingsPath)
168+
/// return UserProfile(user: user, settings: settings)
169+
/// }
170+
///
171+
/// // Use the loaded data
172+
/// self.currentProfile = userData
173+
/// }
174+
/// }
175+
/// ```
176+
///
177+
/// - Parameter operation: The async throwing operation to execute.
178+
/// - Returns: The value returned by the operation if successful.
179+
/// - Throws: An instance of `Self` with the original error wrapped in the `caught` case.
180+
public static func `catch`<ReturnType>(
181+
_ operation: () async throws -> ReturnType
182+
) async throws(Self) -> ReturnType {
183+
do {
184+
return try await operation()
185+
} catch let error as Self {
186+
throw error
138187
} catch {
139188
throw Self.caught(error)
140189
}

0 commit comments

Comments
 (0)