Hay dos puntos importantes para el modelo de manejo de errores Swift 2: exhaustividad y resistencia. Juntos, se reducen a su do
/ catch
sentencia necesitando detectar todos los errores posibles, no solo los que sabe que puede lanzar.
Tenga en cuenta que no declara qué tipos de errores puede lanzar una función, solo si arroja algo. Es un tipo de problema de cero uno-infinito: como alguien que define una función para que otros (incluido su yo futuro) lo usen, no quiere tener que hacer que cada cliente de su función se adapte a cada cambio en la implementación de su función, incluidos los errores que puede arrojar. Desea que el código que llama a su función sea resistente a dicho cambio.
Debido a que su función no puede decir qué tipo de errores arroja (o podría arrojar en el futuro), los catch
bloques que detectan errores no saben qué tipos de errores podría arrojar. Por lo tanto, además de manejar los tipos de error que conoce, debe manejar los que no tiene con una catch
declaración universal ; de esa manera, si su función cambia el conjunto de errores que arroja en el futuro, las personas que llaman aún captarán su errores
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch SandwichError.NotMe {
print("Not me error")
} catch SandwichError.DoItYourself {
print("do it error")
} catch let error {
print(error.localizedDescription)
}
Pero no nos quedemos ahí. Piensa en esta idea de resiliencia un poco más. De la forma en que diseñó su emparedado, debe describir los errores en cada lugar donde los usa. Eso significa que cada vez que cambia el conjunto de casos de error, tiene que cambiar cada lugar que los usa ... no es muy divertido.
La idea detrás de definir sus propios tipos de error es permitirle centralizar cosas como esas. Podría definir un description
método para sus errores:
extension SandwichError: CustomStringConvertible {
var description: String {
switch self {
case NotMe: return "Not me error"
case DoItYourself: return "Try sudo"
}
}
}
Y luego, su código de manejo de errores puede pedirle a su tipo de error que se describa a sí mismo, ahora cada lugar donde maneja errores puede usar el mismo código y manejar posibles casos de errores futuros también.
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch let error as SandwichError {
print(error.description)
} catch {
print("i dunno")
}
Esto también allana el camino para que los tipos de error (o extensiones en ellos) admitan otras formas de informar errores; por ejemplo, podría tener una extensión en su tipo de error que sepa cómo presentar un UIAlertController
informe de error a un usuario de iOS.