Разработка
ErrorKit — сообщения об ошибках Swift, удобные для человека
Сообщения об ошибках Swift могут быть загадочными, но мы, как сообщество, можем сделать их более понятными. Помогите другим (и себе в будущем), добавив лучшие объяснения.
Несмотря на элегантный дизайн Swift, системные сообщения об ошибках часто бывают загадочными и бесполезными. Вместо того чтобы просто жаловаться, я создал ErrorKit, инструмент, который отображает эти сообщения в виде понятных человеку описаний. Но обработка всей экосистемы Apple — слишком большая задача для одного человека, это должна быть работа сообщества.
В этом посте я расскажу о том, как я создал основу для улучшения описаний ошибок, и приглашаю вас присоединиться ко мне в создании всеобъемлющего словаря удобных сообщений об ошибках для разработчиков Swift.
Проблема с системными сообщениями об ошибках
Давайте рассмотрим несколько реальных примеров бесполезных системных сообщений об ошибках:
// File system error "The file couldn't be opened because it doesn't exist." // Better message: "The file 'report.pdf' could not be found. Please verify the file name and location." // Core Data error "The operation couldn't be completed. (Cocoa error 133000.)" // Better message: "The database has a validation error. One or more required fields are empty or have invalid values."
У этих стандартных сообщений есть несколько проблем:
- Они часто слишком техничны для конечных пользователей
- В них отсутствует контекст того, что пытались сделать
- Они редко предлагают решение проблемы
- Иногда они просто неверны или вводят в заблуждение
- Они могут раскрывать детали реализации, которые пользователи не должны видеть
У Apple есть тысячи кодов ошибок для десятков фреймворков, и многие из них существуют уже несколько десятилетий. Хотя новые API были улучшены, многие старые фреймворки по-прежнему возвращают сообщения, предназначенные для разработчиков, а не для пользователей.
Решение: курируемое сообществом отображения ошибок
ErrorKit предоставляет функцию userFriendlyMessage(for:)
, которая сопоставляет системные ошибки с более полезными сообщениями:
do { let data = try Data(contentsOf: url) // Process data... } catch { // Instead of showing the default message // showAlert(error.localizedDescription) // Show an enhanced message showAlert(ErrorKit.userFriendlyMessage(for: error)) }
За кулисами эта функция анализирует ошибку и возвращает более точное описание, основанное на растущем наборе известных типов ошибок:
// Example from ErrorKit's implementation enum FoundationErrorMapper: ErrorMapper { static func userFriendlyMessage(for error: Error) -> String? { let nsError = error as NSError // URL loading errors if nsError.domain == NSURLErrorDomain { switch nsError.code { case NSURLErrorNotConnectedToInternet: return String(localized: "You are not connected to the Internet. Please check your connection.") case NSURLErrorTimedOut: return String(localized: "The request timed out. Please try again later.") // Many more cases... } } // File system errors if nsError.domain == NSCocoaErrorDomain { switch nsError.code { case NSFileNoSuchFileError: return String(localized: "The file could not be found.") // Many more cases... } } // More domains and error codes... return nil // Fall back to default handling } }
Текущее покрытие и примеры
ErrorKit включает в себя отображения для распространенных ошибок в ключевых фреймворках Apple:
Foundation
- Сеть:
NSURLErrorNotConnectedToInternet
→ «Ваше устройство не подключено к интернету. Пожалуйста, проверьте подключение и повторите попытку». - Файловая система:
NSFileNoSuchFileError
→ «Файл report.pdf не найден. Пожалуйста, проверьте имя и расположение файла».
Core Data
- Валидация:
NSValidationErrorMinimum
→ «База данных не подтвердила проверку. Пожалуйста, проверьте введенные данные и повторите попытку». - Управление хранилищем:
NSPersistentStoreCoordinatorError
→ «Ошибка базы данных. Это может быть связано с недавним обновлением приложения или повреждением файла».
MapKit
- Направления:
MKErrorDirectionsNotFound
→ «Для запрашиваемого маршрута не найдены направления». - Местоположение:
MKErrorLocationUnknown
→ «Текущее местоположение недоступно. Проверьте разрешения на местоположение».
Почему нам нужна реакция сообщества
В идеальном мире Apple сама бы исправила бы все свои запутанные сообщения об ошибках. И, честно говоря, они улучшили ситуацию — новые фреймворки, такие как SwiftUI, стали намного понятнее. Но десятилетиями legacy API по-прежнему возвращают загадочные, технические сообщения, к которым, возможно, никто больше никогда не вернется для исправления.
Именно здесь наше сообщество может оказать реальное влияние. Ни один разработчик не видел всех непонятных ошибок, но вместе мы видели большинство из них. Поделившись тем, что мы уже выяснили, и переписав эти сообщения простым языком, мы сможем создать ресурс, который сэкономит время каждого и улучшит работу разработчиков и пользователей.
Как вы можете внести свой вклад
Если вы переписали сообщение о системной ошибке, чтобы сделать его более полезным, вы уже проделали работу — теперь вы можете поделиться ею. Вот 3 основных шага:
- Выявить плохое сообщение
Запишите домен и код ошибки, операцию, которая ее вызвала, и любую полезную информацию из словаряuserInfo
. - Напишите лучшую версию
Используйте простой язык. Будьте конкретны. Предложите полезный следующий шаг, если это имеет смысл. - Отправьте на GitHub
Откройте пул реквест или issue в репозитории ErrorKit с улучшенным сообщением, исходным контекстом и любыми примечаниями.
Даже небольшой вклад может помочь тысячам разработчиков и улучшить пользовательский опыт для миллионов!
За пределами фреймворков Apple: отображение ошибок любой библиотеки
Хотя основное внимание уделяется фреймворкам Apple, система отображения ошибок ErrorKit работает с любыми типами ошибок. Протокол ErrorMapper
позволяет разработчикам создавать кастомные мапперы для сторонних библиотек:
// Example mapper for Alamofire networking errors enum AlamofireErrorMapper: ErrorMapper { static func userFriendlyMessage(for error: Error) -> String? { switch error { case let afError as Alamofire.AFError: switch afError { case .sessionTaskFailed(let underlying): if let urlError = underlying as? URLError { switch urlError.code { case .notConnectedToInternet: return String(localized: "Your device isn't connected to the internet. Please check your connection and try again.") case .timedOut: return String(localized: "The server took too long to respond. Please try again later.") default: return nil } } return nil case .responseValidationFailed(let reason): if case .unacceptableStatusCode(let code) = reason { return String(localized: "The server returned error \(code). Please check your request or try again later.") } return nil default: return nil } default: return nil } } } // Register for immediate use ErrorKit.registerMapper(AlamofireErrorMapper.self)
Эта расширяемость открывает возможности для:
- Добавление кастомных маппингов в ваше приложение для популярных библиотек, таких как Alamofire
- Создание пакетов мапперов для закрытых SDK, таких как Stripe, Admob и т.д.
- Совместное использование маппингов ошибок в командах или организациях
Заключение
Сообщения об ошибках существенно влияют на пользовательский опыт, но часто остаются без внимания при разработке. Функция ErrorKit UserFriendlyMessage(for:)
создает основу для изменения ситуации путем сотрудничества с сообществом, когда разработчики объединяют свои знания, чтобы сделать всю экосистему Swift более удобной для пользователей.
Если вам доводилось расшифровывать загадочные сообщения об ошибках, ваш опыт очень ценен. Внося свой вклад в ErrorKit, вы можете решить эти проблемы не только для себя, но и для всех разработчиков Swift, которые сталкиваются с такими же проблемами. Ознакомьтесь с ErrorKit и поделитесь своими решениями для создания этого ресурса сообщества.
-
Новости3 недели назад
Видео и подкасты о мобильной разработке 2025.22
-
Новости2 недели назад
Видео и подкасты о мобильной разработке 2025.24
-
Вовлечение пользователей4 недели назад
Небольшое изменение в интерфейсе Duolingo, которое меняет все
-
Маркетинг и монетизация4 недели назад
Институциональные покупки: понимание и обнаружение