Найти в Дзене
Цифровая Переплавка

Swift 6 и новая эра обработки ошибок: typed throws и SystemError

Оглавление
Иллюстрация показывает обработку ошибок в Swift 6 — логотип языка, фрагмент кода с throws и визуальные предупреждения, подчёркивающие типобезопасный и удобный подход к диагностике ошибок.
Иллюстрация показывает обработку ошибок в Swift 6 — логотип языка, фрагмент кода с throws и визуальные предупреждения, подчёркивающие типобезопасный и удобный подход к диагностике ошибок.

Swift всегда стремился к безопасности типов, и появление typed throws в версии 6 — это шаг, которого ждали многие разработчики. Теперь можно явно указывать, какие ошибки выбрасывает функция. Это превращает код из «лови всё подряд» в строгий контракт: если функция помечена throws(MyError), она действительно не сможет бросить ничего кроме MyError.

🔹 Зачем это нужно

Раньше throw в Swift напоминал «чёрный ящик»: функция могла вернуть любую ошибку, и компилятору это было всё равно. В итоге:
⚠️ разработчик писал catch { ... }, не понимая, с чем работает;
🔄 приходилось создавать громоздкие enum'ы ошибок без чёткой иерархии;
📉 пользователь часто видел «riddle-style» сообщения вроде
"NSCocoaErrorDomain Code=4" вместо нормального текста.

Typed throws решает это, превращая обработку ошибок в часть интерфейса функции.

🔹 SystemError: протокол нового уровня

Автор статьи The Swift Dev предложил элегантное расширение: протокол SystemError, который добавляет к стандартному Error:

🪵 logMessage — текст для логов разработчика;
🙂
userFriendlyMessage — понятное описание для пользователя;
🧩
underlyingErrors — вложенные ошибки (цепочка, как в Java Exception cause);
🌳
logMessageStack() — рекурсивная печать дерева ошибок с ASCII-ветками;
🔍
lookup() — поиск нужной ошибки внутри стека.

Это превращает обработку ошибок в двухуровневую модель:

  • пользователю — ясный текст,
  • разработчику — полная трассировка.

🔹 Как это работает в коде

struct MyCustomError: SystemError {
var logMessage: String
var userFriendlyMessage: String
var underlyingErrors: [any Error]
}

Теперь функция может объявить:

func parseData() throws(MyCustomError) { ... }

Если внутри произойдёт ошибка декодирования JSON, её можно «обернуть» в MyCustomError с понятным сообщением для пользователя и детальным логом для разработчика.

🔹 Интеграция с Foundation

Особо изящно выглядит адаптация:

  • NSError → сразу подгоняется под SystemError, лог хранит domain и code;
  • DecodingError → преобразуется в структурированные сообщения («Key not found: user.id» вместо «Decoding error»).

То есть даже старые ошибки Swift и Foundation автоматически получают «человеческий» интерфейс.

🔹 Моё видение

Я давно ждал typed throws в Swift, потому что:

🛡️ это повышает надёжность API — документация функции теперь вшита в сигнатуру;
🧑‍💻
улучшает DX (developer experience) — IDE сможет подсказать, какие ошибки реально обрабатывать;
🎯
отделяет уровень пользователя от уровня разработчика — системные детали остаются в логах, а не пугают людей в продакшене.

Фактически, Swift движется к модели Rust: строгая типизация + явное управление ошибками. Только в отличие от Rust, Swift остаётся удобным для быстрого прототипирования.

Итог

Typed throws и SystemError в Swift 6 превращают обработку ошибок в структурированный процесс:

  • 🌱 функции становятся предсказуемее;
  • 🛠️ отладка — прозрачнее;
  • 🙂 пользователи получают понятные сообщения вместо загадочных кодов.

И это, на мой взгляд, одна из самых практичных и «приземлённых» эволюций Swift за последние годы.

Источники