Практическая ситуация: доменная ошибка должна отдавать локализованный текст через localizedDescription, сохраняя при этом типизированный разбор. Какой механизм Swift это обеспечивает?
Для этого тип ошибки должен соответствовать протоколу LocalizedError. Он позволяет предоставить человекочитаемое описание через errorDescription, а исходный тип ошибки при этом сохраняется для разбора в catch или сравнений по вариантам enum.
Базовый протокол Error описывает сам факт сбоя, но не задаёт пользовательский текст. Для отделения машинной классификации ошибки от её представления пользователю в Swift предусмотрен специализированный протокол LocalizedError.
Такой подход решает проблему, при которой разработчику пришлось бы разбирать имя типа или формировать текст непосредственно в месте обработки ошибки. Локализованное представление становится частью контракта ошибки, но не заменяет её структурированные данные.
Если ошибка содержит только варианты enum, вызывающий код может надёжно определить причину сбоя, но пользователь получит техническое или слишком общее сообщение. Если же передавать только строку, типизированный разбор причин будет потерян.
Неверно использовать localizedDescription как машинный идентификатор: текст может измениться из-за локали, редакторских правок или отсутствия локализации. Для программной логики нужно сохранять конкретный тип ошибки и его associated values.
LocalizedError предоставляет несколько необязательных свойств: errorDescription, failureReason, recoverySuggestion и helpAnchor. Наиболее важное для localizedDescription — errorDescription; его значение используется как основное локализованное описание ошибки.
Даже если значение хранится через existentialный тип Error, во время выполнения сохраняется его фактический тип и доступно предоставленное им соответствие LocalizedError. Поэтому интерфейс может получить текст через localizedDescription, а доменный слой — обработать CheckoutError.declined типизированно.
Свойство возвращает String?, потому что конкретная ошибка может не предоставлять описание. Для настоящего приложения строку следует получать из локализационных ресурсов, а не жёстко зашивать в тип ошибки. При этом LocalizedError не делает ошибку Equatable, не задаёт код ошибки и не гарантирует уникальность текста.
Слой оплаты возвращает CheckoutError.declined, а экран оплаты должен показать сообщение пользователю. Возможны два варианта: передавать из слоя оплаты готовую строку или передавать типизированную ошибку и формировать текст в каждом экране.
Готовая строка упрощает отображение, но связывает доменный слой с языком и интерфейсом. Формирование текста в каждом экране сохраняет гибкость, но приводит к дублированию и разным сообщениям для одной причины.
Оптимальный вариант — передавать типизированную ошибку, реализующую LocalizedError, а локализованный текст получать через её контракт. В результате бизнес-логика использует конкретные варианты ошибки, интерфейс получает единое описание, а локализацию можно изменять независимо от алгоритма обработки платежа.
1. Достаточно ли соответствия LocalizedError, чтобы ошибка стала Equatable?
Нет. LocalizedError отвечает только за человекочитаемое представление. Если нужно сравнивать ошибки, конкретный тип должен отдельно соответствовать Equatable, причём сравнение будет доступно для этого конкретного типа, а не для произвольного значения, хранящегося как Error.
2. Сработает ли локализованное описание, если ошибка передана как Error?
Да, при обращении к localizedDescription сохраняется динамический тип значения. Если фактический тип соответствует LocalizedError и предоставляет errorDescription, это описание может быть использовано даже после присваивания значения переменной типа Error. Однако при приведении к Error теряется удобный статический доступ к свойствам конкретного типа и его вариантам.
3. Можно ли использовать localizedDescription как стабильный код ошибки для аналитики или сетевого протокола?
Нет. Это пользовательский текст, зависящий от локализации и формулировок. Для аналитики и обмена между слоями следует использовать типизированные варианты ошибки, отдельные коды или структурированные свойства, а localizedDescription оставлять для отображения человеку.