{"id":28437072,"url":"https://github.com/flinedev/errorkit","last_synced_at":"2025-06-27T20:31:56.436Z","repository":{"id":288615317,"uuid":"690177969","full_name":"FlineDev/ErrorKit","owner":"FlineDev","description":"Simplified error handling with built-in user-friendly messages for common errors. Fully localized. Community-driven.","archived":false,"fork":false,"pushed_at":"2025-06-04T10:59:06.000Z","size":2981,"stargazers_count":347,"open_issues_count":7,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-04T14:10:45.445Z","etag":null,"topics":["debugging","error-handling","swift","swift6","swiftui","typed-throws"],"latest_commit_sha":null,"homepage":"https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FlineDev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-11T17:24:29.000Z","updated_at":"2025-06-04T10:58:59.000Z","dependencies_parsed_at":"2025-06-04T08:40:07.892Z","dependency_job_id":null,"html_url":"https://github.com/FlineDev/ErrorKit","commit_stats":null,"previous_names":["flinedev/errorkit"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/FlineDev/ErrorKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FErrorKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FErrorKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FErrorKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FErrorKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FlineDev","download_url":"https://codeload.github.com/FlineDev/ErrorKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FErrorKit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262327256,"owners_count":23294236,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debugging","error-handling","swift","swift6","swiftui","typed-throws"],"created_at":"2025-06-05T23:08:36.654Z","updated_at":"2025-06-27T20:31:56.402Z","avatar_url":"https://github.com/FlineDev.png","language":"Swift","readme":"![ErrorKit Logo](https://github.com/FlineDev/ErrorKit/blob/main/Logo.png?raw=true)\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FFlineDev%2FErrorKit%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/FlineDev/ErrorKit)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FFlineDev%2FErrorKit%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/FlineDev/ErrorKit)\n\n# ErrorKit\n\nMaking error handling in Swift more intuitive and powerful with clearer messages, type safety, and user-friendly diagnostics.\n\n## Overview\n\nSwift's error handling has several limitations that make it challenging to create robust, user-friendly applications:\n- The `Error` protocol's confusing behavior with `localizedDescription`\n- Hard-to-understand system error messages\n- Limited type safety in error propagation\n- Difficulties with error chain debugging (relevant for typed throws!)\n- Challenges in collecting meaningful feedback from users\n\nErrorKit addresses these challenges with a suite of lightweight, interconnected features you can adopt progressively.\n\n## Core Features\n\n### The Throwable Protocol\n\n`Throwable` fixes the confusion of Swift's `Error` protocol by providing a clear, Swift-native approach to error handling:\n\n```swift\nenum NetworkError: Throwable {\n   case noConnectionToServer\n   case parsingFailed\n\n   var userFriendlyMessage: String {\n      switch self {\n      case .noConnectionToServer:\n         String(localized: \"Unable to connect to the server.\")\n      case .parsingFailed:\n         String(localized: \"Data parsing failed.\")\n      }\n   }\n}\n```\n\nNow when catching this error, you'll see exactly what you expect:\n```\n\"Unable to connect to the server.\"\n```\n\nFor rapid development, you can use string raw values:\n\n```swift\nenum NetworkError: String, Throwable {\n   case noConnectionToServer = \"Unable to connect to the server.\"\n   case parsingFailed = \"Data parsing failed.\"\n}\n```\n\n[Read more about Throwable →](https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit/throwable-protocol)\n\n### Enhanced Error Descriptions\n\nGet improved, user-friendly messages for ANY error, including system errors:\n\n```swift\ndo {\n    let _ = try Data(contentsOf: url)\n} catch {\n    // Better than localizedDescription, works with any error type\n    print(ErrorKit.userFriendlyMessage(for: error))\n    // \"You are not connected to the Internet. Please check your connection.\"\n    \n    // String interpolation automatically uses userFriendlyMessage(for:)\n    print(\"Request failed: \\(error)\")\n}\n```\n\nThese 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.\n\n[Read more about Enhanced Error Descriptions →](https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit/enhanced-error-descriptions)\n\n## Swift 6 Typed Throws Support\n\nSwift 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:\n\n### Error Nesting with Catching\n\nThe `Catching` protocol solves the biggest problem with error handling: nested errors.\n\n```swift\nenum ProfileError: Throwable, Catching {\n    case validationFailed(field: String)\n    case caught(Error)  // Single case handles all nested errors!\n    \n    var userFriendlyMessage: String { /* ... */ }\n}\n\nstruct ProfileRepository {\n    func loadProfile(id: String) throws(ProfileError) -\u003e UserProfile {\n        // Regular error throwing for validation\n        guard id.isValidFormat else {\n            throw ProfileError.validationFailed(field: \"id\")\n        }\n        \n        // Automatically wrap any database or file errors\n        let userData = try ProfileError.catch {\n            let user = try database.loadUser(id)\n            let settings = try fileSystem.readUserSettings(user.settingsPath)\n            return UserProfile(user: user, settings: settings)\n        }\n        \n        return userData\n    }\n}\n```\n\n[Read more about Typed Throws and Error Nesting →](https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit/typed-throws-and-error-nesting)\n\n### Error Chain Debugging\n\nWhen using `Throwable` with the `Catching` protocol, you get powerful error chain debugging:\n\n```swift\ndo {\n    try await updateUserProfile()\n} catch {\n    print(ErrorKit.errorChainDescription(for: error))\n    \n    // Output shows the complete error path:\n    // ProfileError\n    // └─ DatabaseError\n    //    └─ FileError.notFound(path: \"/Users/data.db\")\n    //       └─ userFriendlyMessage: \"Could not find database file.\"\n}\n```\n\n[Read more about Error Chain Debugging →](https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit/error-chain-debugging)\n\n## Ready-to-Use Tools\n\n### Built-in Error Types\n\nStop reinventing common error types in every project. ErrorKit provides standardized error types for common scenarios:\n\n```swift\nfunc fetchUserData() throws(DatabaseError) {\n    guard isConnected else {\n        throw .connectionFailed\n    }\n    // Fetching logic\n}\n```\n\nIncludes ready-to-use types like `DatabaseError`, `NetworkError`, `FileError`, `ValidationError`, `PermissionError`, and more – all conforming to both `Throwable` and `Catching` with localized messages.\n\nFor quick one-off errors, use `GenericError`:\n\n```swift\nfunc quickOperation() throws {\n    guard condition else {\n        throw GenericError(userFriendlyMessage: \"The operation couldn't be completed due to invalid state.\")\n    }\n    // Operation logic\n}\n```\n\n[Read more about Built-in Error Types →](https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit/built-in-error-types)\n\n### User Feedback with Error Logs\n\nGathering diagnostic information from users has never been simpler:\n\n```swift\nButton(\"Report a Problem\") {\n    showMailComposer = true\n}\n.mailComposer(\n    isPresented: $showMailComposer,\n    recipient: \"support@yourapp.com\",\n    subject: \"Bug Report\",\n    messageBody: \"Please describe what happened:\",\n    attachments: [\n        try? ErrorKit.logAttachment(ofLast: .minutes(30))\n    ]\n)\n```\n\nWith 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.\n\n[Read more about User Feedback and Logging →](https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit/user-feedback-with-logs)\n\n## How These Features Work Together\n\nErrorKit's features are designed to complement each other while remaining independently useful:\n\n1. **Start with improved error definitions** using `Throwable` for custom errors and `userFriendlyMessage(for:)` for system errors.\n\n2. **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.\n\n3. **Save time with ready-made tools**: built-in error types for common scenarios and simple log collection for user feedback.\n\n4. **Extend with custom mappers**: Create error mappers for any library to improve error messages across your entire application.\n\n## Adoption Path\n\nHere's a practical adoption strategy:\n\n1. Replace `Error` with `Throwable` in your custom error types\n2. Use `ErrorKit.userFriendlyMessage(for:)` when showing system errors\n3. Adopt built-in error types where they fit your needs\n4. Implement typed throws with `Catching` for more robust error flows\n5. Add error chain debugging to improve error visibility\n6. Integrate log collection with your feedback system\n\n## Documentation\n\nFor complete documentation visit:\n[ErrorKit Documentation](https://swiftpackageindex.com/FlineDev/ErrorKit/documentation/errorkit)\n\n## Showcase\n\nI created this library for my own Indie apps (download \u0026 rate them to show your appreciation):\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eApp Icon\u003c/th\u003e\n    \u003cth\u003eApp Name \u0026 Description\u003c/th\u003e\n    \u003cth\u003eSupported Platforms\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6476773066?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/FlineDev/HandySwiftUI/main/Images/Apps/TranslateKit.webp\" width=\"64\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6476773066?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cstrong\u003eTranslateKit: App Localization\u003c/strong\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      AI-powered app localization with unmatched accuracy. Fast \u0026 easy: AI \u0026 proofreading, 125+ languages, market insights. Budget-friendly, free to try.\n    \u003c/td\u003e\n    \u003ctd\u003eMac\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6502914189?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/FlineDev/HandySwiftUI/main/Images/Apps/FreemiumKit.webp\" width=\"64\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6502914189?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cstrong\u003eFreemiumKit: In-App Purchases for Indies\u003c/strong\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      Simple In-App Purchases and Subscriptions: Automation, Paywalls, A/B Testing, Live Notifications, PPP, and more.\n    \u003c/td\u003e\n    \u003ctd\u003eiPhone, iPad, Mac, Vision\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6587583340?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/FlineDev/HandySwiftUI/main/Images/Apps/PleydiaOrganizer.webp\" width=\"64\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6587583340?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cstrong\u003ePleydia Organizer: Movie \u0026 Series Renamer\u003c/strong\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      Simple, fast, and smart media management for your Movie, TV Show and Anime collection.\n    \u003c/td\u003e\n    \u003ctd\u003eMac\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6480134993?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/FlineDev/HandySwiftUI/main/Images/Apps/FreelanceKit.webp\" width=\"64\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6480134993?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cstrong\u003eFreelanceKit: Project Time Tracking\u003c/strong\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      Simple \u0026 affordable time tracking with a native experience for all devices. iCloud sync \u0026 CSV export included.\n    \u003c/td\u003e\n    \u003ctd\u003eiPhone, iPad, Mac, Vision\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6472669260?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/FlineDev/HandySwiftUI/main/Images/Apps/CrossCraft.webp\" width=\"64\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6472669260?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cstrong\u003eCrossCraft: Custom Crosswords\u003c/strong\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      Create themed \u0026 personalized crosswords. Solve them yourself or share them to challenge others.\n    \u003c/td\u003e\n    \u003ctd\u003eiPhone, iPad, Mac, Vision\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6477829138?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/FlineDev/HandySwiftUI/main/Images/Apps/FocusBeats.webp\" width=\"64\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6477829138?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cstrong\u003eFocusBeats: Pomodoro + Music\u003c/strong\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      Deep Focus with proven Pomodoro method \u0026 select Apple Music playlists \u0026 themes. Automatically pauses music during breaks.\n    \u003c/td\u003e\n    \u003ctd\u003eiPhone, iPad, Mac, Vision\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6478062053?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/FlineDev/HandySwiftUI/main/Images/Apps/Posters.webp\" width=\"64\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://apps.apple.com/app/apple-store/id6478062053?pt=549314\u0026ct=github.com\u0026mt=8\"\u003e\n        \u003cstrong\u003ePosters: Discover Movies at Home\u003c/strong\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      Auto-updating \u0026 interactive posters for your home with trailers, showtimes, and links to streaming services.\n    \u003c/td\u003e\n    \u003ctd\u003eVision\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflinedev%2Ferrorkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflinedev%2Ferrorkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflinedev%2Ferrorkit/lists"}