Simplified error handling with built-in user-friendly messages for common errors. Fully localized. Community-driven.
Making error handling in Swift more intuitive and powerful with clearer messages, type safety, and user-friendly diagnostics.
Swift’s error handling has several limitations that make it challenging to create robust, user-friendly applications:
Error
protocol’s confusing behavior with localizedDescription
ErrorKit addresses these challenges with a suite of lightweight, interconnected features you can adopt progressively.
Throwable
fixes the confusion of Swift’s Error
protocol by providing a clear, Swift-native approach to error handling:
enum NetworkError: Throwable {
case noConnectionToServer
case parsingFailed
var userFriendlyMessage: String {
switch self {
case .noConnectionToServer:
String(localized: "Unable to connect to the server.")
case .parsingFailed:
String(localized: "Data parsing failed.")
}
}
}
Now when catching this error, you’ll see exactly what you expect:
"Unable to connect to the server."
For rapid development, you can use string raw values:
enum NetworkError: String, Throwable {
case noConnectionToServer = "Unable to connect to the server."
case parsingFailed = "Data parsing failed."
}
Get improved, user-friendly messages for ANY error, including system errors:
do {
let _ = try Data(contentsOf: url)
} catch {
// Better than localizedDescription, works with any error type
print(ErrorKit.userFriendlyMessage(for: error))
// "You are not connected to the Internet. Please check your connection."
}
These enhanced descriptions are community-provided and fully localized mappings of common system errors to clearer, more actionable messages. ErrorKit comes with built-in mappers for Foundation, CoreData, MapKit, and more. You can also create custom mappers for third-party libraries or your own error types.
Read more about Enhanced Error Descriptions →
Swift 6 introduces typed throws (throws(ErrorType)
), bringing compile-time type checking to error handling. ErrorKit makes this powerful feature practical with solutions for its biggest challenges:
The Catching
protocol solves the biggest problem with error handling: nested errors.
enum ProfileError: Throwable, Catching {
case validationFailed(field: String)
case caught(Error) // Single case handles all nested errors!
var userFriendlyMessage: String { /* ... */ }
}
struct ProfileRepository {
func loadProfile(id: String) throws(ProfileError) -> UserProfile {
// Regular error throwing for validation
guard id.isValidFormat else {
throw ProfileError.validationFailed(field: "id")
}
// Automatically wrap any database or file errors
let userData = try ProfileError.catch {
let user = try database.loadUser(id)
let settings = try fileSystem.readUserSettings(user.settingsPath)
return UserProfile(user: user, settings: settings)
}
return userData
}
}
Read more about Typed Throws and Error Nesting →
When using Throwable
with the Catching
protocol, you get powerful error chain debugging:
do {
try await updateUserProfile()
} catch {
Logger().error("\(ErrorKit.errorChainDescription(for: error))")
// Output shows the complete error path:
// ProfileError
// └─ DatabaseError
// └─ FileError.notFound(path: "/Users/data.db")
// └─ userFriendlyMessage: "Could not find database file."
}
Read more about Error Chain Debugging →
Stop reinventing common error types in every project. ErrorKit provides standardized error types for common scenarios:
func fetchUserData() throws(DatabaseError) {
guard isConnected else {
throw .connectionFailed
}
// Fetching logic
}
Includes ready-to-use types like DatabaseError
, NetworkError
, FileError
, ValidationError
, PermissionError
, and more – all conforming to both Throwable
and Catching
with localized messages.
For quick one-off errors, use GenericError
:
func quickOperation() throws {
guard condition else {
throw GenericError(userFriendlyMessage: "The operation couldn't be completed due to invalid state.")
}
// Operation logic
}
Read more about Built-in Error Types →
Gathering diagnostic information from users has never been simpler:
Button("Report a Problem") {
showMailComposer = true
}
.mailComposer(
isPresented: $showMailComposer,
recipient: "support@yourapp.com",
subject: "Bug Report",
messageBody: "Please describe what happened:",
attachments: [
try? ErrorKit.logAttachment(ofLast: .minutes(30))
]
)
With just a simple built-in SwiftUI modifier and the logAttachment
helper function, you can easily include all log messages from Apple’s unified logging system and let your users send them to you via email. Other integrations are also supported.
Read more about User Feedback and Logging →
ErrorKit’s features are designed to complement each other while remaining independently useful:
Start with improved error definitions using Throwable
for custom errors and userFriendlyMessage(for:)
for system errors.
Add type safety with Swift 6 typed throws, using the Catching
protocol to solve nested error challenges. This pairs with error chain debugging to understand error flows through your app.
Save time with ready-made tools: built-in error types for common scenarios and simple log collection for user feedback.
Extend with custom mappers: Create error mappers for any library to improve error messages across your entire application.
Here’s a practical adoption strategy:
Error
with Throwable
in your custom error typesErrorKit.userFriendlyMessage(for:)
when showing system errorsCatching
for more robust error flowsFor complete documentation visit:
ErrorKit Documentation
I created this library for my own Indie apps (download & rate them to show your appreciation):
App Icon | App Name & Description | Supported Platforms |
---|---|---|
![]() |
TranslateKit: App Localization
AI-powered app localization with unmatched accuracy. Fast & easy: AI & proofreading, 125+ languages, market insights. Budget-friendly, free to try. |
Mac |
![]() |
FreemiumKit: In-App Purchases for Indies
Simple In-App Purchases and Subscriptions: Automation, Paywalls, A/B Testing, Live Notifications, PPP, and more. |
iPhone, iPad, Mac, Vision |
![]() |
Pleydia Organizer: Movie & Series Renamer
Simple, fast, and smart media management for your Movie, TV Show and Anime collection. |
Mac |
![]() |
FreelanceKit: Project Time Tracking
Simple & affordable time tracking with a native experience for all devices. iCloud sync & CSV export included. |
iPhone, iPad, Mac, Vision |
![]() |
CrossCraft: Custom Crosswords
Create themed & personalized crosswords. Solve them yourself or share them to challenge others. |
iPhone, iPad, Mac, Vision |
![]() |
FocusBeats: Pomodoro + Music
Deep Focus with proven Pomodoro method & select Apple Music playlists & themes. Automatically pauses music during breaks. |
iPhone, iPad, Mac, Vision |
![]() |
Posters: Discover Movies at Home
Auto-updating & interactive posters for your home with trailers, showtimes, and links to streaming services. |
Vision |