Site icon AppTractor

Типизированные ошибки (typed throws) в Swift с примерами

Типизированные ошибки (typed throws) появились в Xcode 16 и позволяют определять тип ошибки, которую выбрасывает метод. Вместо того чтобы обрабатывать любую ошибку, вы можете обрабатывать конкретные случаи и получать преимущество от проверки во время компиляции для вновь добавленных экземпляров. Такие ошибки были представлены и разработаны в предложении Swift Evolution SE-413.

Преимущества Typed throws

Я рекомендую вам прочитать “Try Catch Throw: Обработка ошибок в Swift с примерами кода”, прежде чем погружаться в типизированные ошибки, чтобы вы были полностью осведомлены об основах обработки ошибок в Swift. В этой статье мы продолжим тот же путь, используя аналогичные примеры кода.

Указание типа ошибки

Представьте, что у вас есть следующий код валидатора имени пользователя, который уже работает с определенным типом ошибки:

struct UsernameValidator {
    enum ValidationError: Error {
        case emptyName
        case nameToShort(nameLength: Int)
    }
    
    static func validate(name: String) throws {
        guard !name.isEmpty else {
            throw ValidationError.emptyName
        }
        guard name.count > 2 else {
            throw ValidationError.nameToShort(nameLength: name.count)
        }
    }
}

Во всех случаях неудачи тип будет ValidationError. Это позволяет нам использовать типизированные ошибки внутри определения метода:

/// Using throws(ValidationError) we specify the error type to always be `ValidationError`
static func validate(name: String) throws(ValidationError) {
    guard !name.isEmpty else {
        throw ValidationError.emptyName
    }
    guard name.count > 2 else {
        throw ValidationError.nameToShort(nameLength: name.count)
    }
}

Определяя ожидаемую ошибку, мы получаем преимущества от проверок во время компиляции и автодополнения. Мы можем переписать приведенный выше метод без  определения типа ValidationError в inline:

static func validate(name: String) throws(ValidationError) {
    guard !name.isEmpty else {
        throw .emptyName
    }
    guard name.count > 2 else {
        throw .nameToShort(nameLength: name.count)
    }
}

Автозавершение достаточно умно, чтобы определить тип ошибки и помочь вам соответствующим образом:

Вы можете воспользоваться автодополнение при использовании типизированных ошибок.

Наконец, компилятор проверит и выдаст ошибку, если вы пытаетесь ошибиться с другим типом:

Компилятор выдаст ошибку, если вы пытаетесь выдать другую ошибку.

Поскольку мы пытаемся выбросить OtherError вместо ValidationError, мы столкнулись со следующей ошибкой:

Thrown expression type ‘UsernameValidator.OtherError’ cannot be converted to error type ‘UsernameValidator.ValidationError’

Typed throws в Swift помогает сделать код более предсказуемым и безопасным, позволяя точно указывать, какие ошибки может выбросить функция. Проверки во время компиляции очень ценны и также их можно использовать при обработке ошибок внутри предложения do-catch.

Источник

Exit mobile version