Skip to content

Add an async variant to Catching.catch #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 3, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions Sources/ErrorKit/Catching.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,55 @@ extension Catching {
) throws(Self) -> ReturnType {
do {
return try operation()
} catch let error as Self {
throw error
} catch {
throw Self.caught(error)
}
}

/// Executes an async throwing operation and automatically wraps any thrown errors into this error type's `caught` case,
/// while passing through the operation's return value on success. Great for functions using typed throws.
///
/// # Overview
/// This function provides a convenient way to:
/// - Execute async throwing operations
/// - Automatically wrap any errors into the current error type
/// - Pass through return values from the wrapped code
/// - Maintain type safety with typed throws
///
/// # Example
/// ```swift
/// struct ProfileRepository {
/// func loadProfile(id: String) throws(ProfileError) {
/// // Regular error throwing for validation
/// guard id.isValidFormat else {
/// throw ProfileError.validationFailed(field: "id")
/// }
///
/// // Automatically wrap any database or file errors while handling return value
/// let userData = try await ProfileError.catch {
/// let user = try await database.loadUser(id)
/// let settings = try await fileSystem.readUserSettings(user.settingsPath)
/// return UserProfile(user: user, settings: settings)
/// }
///
/// // Use the loaded data
/// self.currentProfile = userData
/// }
/// }
/// ```
///
/// - Parameter operation: The async throwing operation to execute.
/// - Returns: The value returned by the operation if successful.
/// - Throws: An instance of `Self` with the original error wrapped in the `caught` case.
public static func `catch`<ReturnType>(
_ operation: () async throws -> ReturnType
) async throws(Self) -> ReturnType {
do {
return try await operation()
} catch let error as Self {
throw error
} catch {
throw Self.caught(error)
}
Expand Down