Până la Swift 6, cuvântul cheie throws putea propaga orice tip de eroare ascuns în spatele protocolului de tip existențial any Error. Deși flexibil, acest mecanism introducea costuri de alocare dinamică și forța dezvoltatorii să folosească clauze exhaustive catch generice, fără ca compilatorul să poată garanta tipul exact al erorilor posibile.
Swift 6 introduce o funcționalitate cerută de mult timp de comunitate: Typed Throws (aruncarea erorilor tipizate). Sintaxa throws(TipEroare) permite specificarea precisă a contractului de erori la nivel de semnătură de funcție.
// 1. Definirea enumerării specifice de erori:
enum ParserError: Error {
case jsonInvalid(linie: Int)
case campLipsa(String)
case formatIncompatibil
}
struct Utilizator {
let id: Int
let email: String
}
// 2. Semnătura funcției declară exact tipul de eroare aruncat:
func parseazaUtilizator(payload: [String: Any]) throws(ParserError) -> Utilizator {
guard let id = payload["id"] as? Int else {
throw .campLipsa("id")
}
guard let email = payload["email"] as? String else {
throw .campLipsa("email")
}
return Utilizator(id: id, email: email)
}
// 3. Consumul funcției: Blocul catch este 100% tipizat și exhaustiv!
do {
let dateExemplu: [String: Any] = ["id": 42]
let u = try parseazaUtilizator(payload: dateExemplu)
print("Utilizator creat: \(u.email)")
} catch {
// Compilatorul știe automat că 'error' este de tip 'ParserError', nu 'any Error'!
switch error {
case .jsonInvalid(let linie):
print("Eroare JSON pe linia: \(linie)")
case .campLipsa(let camp):
print("Lipsește câmpul obligatoriu: \(camp)")
case .formatIncompatibil:
print("Format general neacceptat.")
}
}
Relația dintre Typed Throws și Tipul Result
Swift permite conversia bidirecțională directă între funcțiile cu erori tipizate și tipul enumerare Result<Success, Failure>:
// Crearea unui Result dintr-o operație cu typed throws:
let rezultat: Result<Utilizator, ParserError> = Result {
try parseazaUtilizator(payload: ["id": 1, "email": "test@dexblog.ro"])
}
// Extragerea valorii înapoi cu typed throws:
do {
let valoare = try rezultat.get()
print("Succes: \(valoare.email)")
} catch {
print("Eroare tipizată: \(error)")
}