Menu
Coddy logo textTech

do, try, catch

Parte de la sección Lógica y Flujo del Journey de Swift de Coddy — lección 45 de 56.

La forma completa para manejar errores es do/try/catch:

enum DivError: Error { case byZero }

func divide(_ a: Int, _ b: Int) throws -> Int {
    if b == 0 { throw DivError.byZero }
    return a / b
}

do {
    let r = try divide(10, 2)
    print(r)                      // 5
} catch DivError.byZero {
    print("can't divide by zero")
} catch {
    print("unknown error")
}

try va delante de cualquier llamada que lance un error. Si la llamada lanza un error, el control salta al catch correspondiente; de lo contrario, la ejecución continúa después del bloque do.

Múltiples cláusulas catch se ejecutan de arriba a abajo y la primera coincidencia gana, al igual que un switch. El catch simple al final es el que captura todo, casi siempre querrás uno para mantener contento al compilador.

challenge icon

Desafío

Fácil

Define un enum ParseError: Error con tres casos: empty, notInteger y negative.

Define una función que lanza errores parsePositive(_ s: String) throws -> Int que:

  • Lanza .empty cuando s eliminando los espacios en blanco está vacío
  • Lanza .notInteger cuando s no puede ser analizado como Int
  • Lanza .negative cuando el valor analizado es < 0
  • De lo contrario, devuelve el valor analizado

Lee una sola línea de stdin y llama a parsePositive en un bloque do/catch. Imprime:

  • got: <n> en caso de éxito
  • error: empty, error: not integer o error: negative para cada caso

Para la entrada 42, la salida es got: 42. Para una línea vacía, es error: empty. Para abc es error: not integer.

Hoja de referencia

El manejo de errores en Swift utiliza do/try/catch. Define errores con un enum que cumpla con Error, marca las funciones que lanzan errores con throws y utiliza throw para lanzar un error:

enum DivError: Error { case byZero }

func divide(_ a: Int, _ b: Int) throws -> Int {
    if b == 0 { throw DivError.byZero }
    return a / b
}

do {
    let r = try divide(10, 2)
    print(r)                      // 5
} catch DivError.byZero {
    print("can't divide by zero")
} catch {
    print("unknown error")        // captura todo
}
  • try debe preceder a cada llamada que lance un error.
  • Las cláusulas catch se comparan de arriba hacia abajo; la primera coincidencia gana.
  • Un catch simple al final actúa como un capturador para todo.

Pruébalo tú mismo

let line = readLine()!

// TODO: enum ParseError; func parsePositive(_:) throws -> Int;
// do/try/catch con tres ramas más la rama por defecto
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Lógica y Flujo