Menu
Coddy logo textTech

Propagando Erros

Parte da seção Lógica e Fluxo do Journey de Swift da Coddy — lição 47 de 56.

Uma função que lança erros pode chamar outras funções que lançam erros. O erro propaga-se até o do/catch mais próximo automaticamente, sem a necessidade de relançamento manual.

enum AuthError: Error { case badUser, badPass }

func loadUser(_ name: String) throws -> String {
    if name.isEmpty { throw AuthError.badUser }
    return name
}

func login(_ name: String, _ pass: String) throws -> String {
    let u = try loadUser(name)            // encaminha o erro
    if pass.count < 4 { throw AuthError.badPass }
    return "hello \(u)"
}

do {
    print(try login("", "abcd"))
} catch AuthError.badUser {
    print("missing user")
} catch AuthError.badPass {
    print("weak password")
}

Leia de cima para baixo: login chama loadUser com try. Se loadUser lançar um erro, o erro ignora o corpo de login e cai no catch externo. Você escreve cada etapa para falhar rapidamente e deixar que quem chama decida o que fazer.

challenge icon

Desafio

Médio

Construa um pequeno pipeline de duas etapas que lançam erros (throwing steps).

Defina StepError: Error com dois casos: negative, tooBig.

Defina parseSafe(_ s: String) throws -> Int: lança .negative quando o inteiro analisado for menor que 0, caso contrário, o retorna. (Assuma que a entrada é analisada corretamente, você já tratou isso em outro lugar.)

Defina capStrict(_ n: Int) throws -> Int: lança .tooBig quando n > 100, caso contrário, retorna n.

Defina processStep(_ s: String) throws -> Int que chama parseSafe e depois capStrict, permitindo que qualquer erro se propague.

Leia uma única linha de entrada: uma lista de strings separadas por vírgulas. Para cada uma, chame processStep em um bloco do/catch e imprima uma linha:

  • ok: <n> em caso de sucesso
  • negative quando parseSafe lançar erro
  • too big quando capStrict lançar erro

Para a entrada 10,-1,200,42, a saída é:

ok: 10
negative
too big
ok: 42

Folha de consulta

Uma função que lança erros (throwing function) pode chamar outras funções que lançam erros com try. Os erros se propagam automaticamente até o do/catch mais próximo:

enum AuthError: Error { case badUser, badPass }

func loadUser(_ name: String) throws -> String {
    if name.isEmpty { throw AuthError.badUser }
    return name
}

func login(_ name: String, _ pass: String) throws -> String {
    let u = try loadUser(name)   // o erro se propaga se for lançado
    if pass.count < 4 { throw AuthError.badPass }
    return "hello \(u)"
}

do {
    print(try login("", "abcd"))
} catch AuthError.badUser {
    print("missing user")
} catch AuthError.badPass {
    print("weak password")
}

Se loadUser lançar um erro, a execução pula o restante de login e cai diretamente no catch externo. Não é necessário relançar o erro manualmente.

Experimente você mesmo

let parts = readLine()!.components(separatedBy: ",")

// TODO: enum StepError; parseSafe; capStrict; processStep;
// para cada parte, faça/tente processStep, capture cada ramificação, imprima
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Lógica e Fluxo