Propagación de errores
Parte de la sección Lógica y Flujo del Journey de Swift de Coddy — lección 47 de 56.
Una función que lanza errores puede llamar a otras funciones que lanzan errores. El error se propaga automáticamente hasta el do/catch más cercano, sin necesidad de relanzarlo manualmente.
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) // propaga el error
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")
}Lee de arriba a abajo: login llama a loadUser con try. Si loadUser lanza un error, el error se salta el cuerpo de login y cae en el catch externo. Escribes cada paso para que falle rápido y dejas que quien llama decida qué hacer.
Desafío
IntermedioConstruye una pequeña canalización de dos pasos que lanzan errores.
Define StepError: Error con dos casos: negative, tooBig.
Define parseSafe(_ s: String) throws -> Int: lanza .negative cuando el entero analizado es menor que 0, de lo contrario lo devuelve. (Asume que la entrada se analiza correctamente, ya has manejado eso en otro lugar).
Define capStrict(_ n: Int) throws -> Int: lanza .tooBig cuando n > 100, de lo contrario devuelve n.
Define processStep(_ s: String) throws -> Int que llame a parseSafe y luego a capStrict, permitiendo que cualquier error se propague.
Lee una sola línea de entrada: una lista de cadenas separadas por comas. Para cada una, llama a processStep en un bloque do/catch e imprime una línea:
ok: <n>en caso de éxitonegativecuandoparseSafelanzó un errortoo bigcuandocapStrictlanzó un error
Para la entrada 10,-1,200,42, la salida es:
ok: 10
negative
too big
ok: 42Hoja de referencia
Una función que lanza errores puede llamar a otras funciones que lanzan errores con try. Los errores se propagan automáticamente hasta el do/catch más cercano:
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) // el error se propaga si se lanza
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")
}Si loadUser lanza un error, la ejecución se salta el resto de login y llega directamente al catch externo. No es necesario volver a lanzar el error manualmente.
Pruébalo tú mismo
let parts = readLine()!.components(separatedBy: ",")
// TODO: enum StepError; parseSafe; capStrict; processStep;
// para cada parte, hacer/intentar processStep, capturar cada rama, imprimir
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
1Strings a fondo
Conteo e índicesMayúsculas, minúsculas y TrimBúsqueda en StringsDividir y unirReemplazo de subcadenasResumen: Validación de usuario4Conjuntos
Crear conjuntosUnión e intersecciónResta y diferencia simétricaSubconjunto y superconjuntoResumen - Filtro de etiquetas7Proyecto - Seguimiento de hábitos
Descripción general del proyectoMarcar como completado10Proyecto - Motor de cuestionarios
Descripción general del proyectoHacer preguntas2Rangos e Intervalos
Cerrados vs. SemiabiertosSaltos (Stride)Métodos de RangosRangos en SwitchResumen - Cuadrícula de calendario5Funciones de orden superior Pt. 1
MapFilterReduceEncadenar map, filter, reduceResumen - Estadísticas de palabras3Diccionarios
Declaración de diccionariosBúsqueda opcionalActualización de diccionariosIteración de diccionariosAgrupación de valoresResumen - Inventario6Funciones de orden superior - Parte 2
compactMapflatMapsorted(by:)Construcción de pipelinesRepaso - Tabla de posiciones9Manejo de errores
throws y Errordo, try, catchtry? y try!Propagación de erroresRepaso - Calculadora segura