Как выбросить ошибку/исключение с собственным сообщением в Swift (простой способ)?
Простой способ: создаём кастомную ошибку через enum
Да, в Swift нельзя просто выбросить строку — это не соответствует строгой системе типов. Но есть очень лаконичный способ, который не требует написания десятков строк. Нужно всего лишь объявить один enum с одним кейсом, который содержит строку:
enum MyError: Error {
case custom(String)
}
// Использование:
let age = 15
if age < 18 {
throw MyError.custom("Пользователь несовершеннолетний")
}
Это минимально возможная конструкция. Если вам нужно больше разных ошибок — просто добавьте кейсы:
enum AuthError: Error {
case invalidEmail
case weakPassword(String)
case userNotFound
}
// Выброс с сообщением:
throw AuthError.weakPassword("Пароль должен быть длиннее 8 символов")
Как перехватывать и извлекать сообщение
При обработке ошибки вы можете получить сообщение через switch или if case let:
do {
let age = 15
if age < 18 {
throw MyError.custom("Пользователь несовершеннолетний")
}
} catch MyError.custom(let message) {
print("Ошибка: \(message)") // Выведет: Ошибка: Пользователь несовершеннолетний
} catch {
print("Другая ошибка: \(error)")
}
Ещё более короткий вариант (для продвинутых)
Если вы совсем не хотите объявлять enum, можно использовать структуру с протоколом LocalizedError:
struct SimpleError: LocalizedError {
let message: String
var errorDescription: String? { message }
}
// Использование:
throw SimpleError(message: "Что-то пошло не так")
// Перехват:
catch let error as SimpleError {
print(error.message) // или error.localizedDescription
}
Важные моменты
- Всегда используйте do-catch — если не обработать throwing функцию, код не скомпилируется (кроме случаев с
try!, но это опасно). - Enum с associated value — это идиоматичный Swift-способ. Он даёт автодополнение и безопасность типов.
- Не используйте строки как ошибки — в крупных проектах это усложняет отладку. Лучше создать отдельный enum для каждого модуля.
Таким образом, самый простой способ — это однострочный enum. Он занимает 2 строки в объявлении и 1 строку при выбросе. Это стандартная практика в Swift-сообществе.
<<Альтернатива: использование NSError (для совместимости с Objective-C)
Если вам нужно быстро прототипировать или работать с legacy кодом, можно использовать NSError — он уже реализует протокол Error:
throw NSError(domain: "com.example.app",
code: 1001,
userInfo: [NSLocalizedDescriptionKey: "Моё кастомное сообщение"])
Преимущества:
- Не нужно объявлять собственный тип
- Работает с Objective-C API
- Громоздкая запись (много параметров)
- Нет проверки типов на этапе компиляции
- Сложнее отлавливать конкретные ошибки
Для простых проверок это может быть быстрее, чем создавать enum, но для production-кода лучше использовать кастомные типы. Если вам нужно выбросить ошибку буквально в 2-3 местах — NSError подойдёт, но не злоупотребляйте им.