programowanieProgramista iOS

Opisz, jak działa zarządzanie błędami (Error Handling) w Swift. Jakie są typy błędów, jakie są sposoby ich przetwarzania, kiedy lepiej używać throw/catch, a kiedy — Result?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Swift wspiera ścisły system zarządzania błędami przez protokół Error oraz konstrukcje throw, try, catch. Możesz zdefiniować własne typy błędów, dziedzicząc po Error:

enum NetworkError: Error { case noInternet case serverError(code: Int) case unknown }

Funkcje, które mogą wyrzucić błąd, są deklarowane z throws:

func fetchData() throws -> Data { // ... throw NetworkError.noInternet }

Błędy można przetwarzać za pomocą bloku do-catch:

do { let data = try fetchData() // Praca z danymi } catch NetworkError.noInternet { print("Brak internetu") } catch { print("Inny błąd: \(error)") }

Alternatywnym podejściem jest typ Result<T, Error>, który pozwala zwracać rezultat albo błąd bez potrzeby użycia try-catch:

func fetchData() -> Result<Data, NetworkError> { // ... return .failure(.noInternet) } let result = fetchData() switch result { case .success(let data): // OK case .failure(let err): // Przetwarzanie błędu }

Kiedy używać:

  • Użyj try/catch, jeśli błąd jest krytyczny i nie można go zignorować.
  • Użyj Result, jeśli funkcja jest asynchroniczna lub gdy wygodniej jest przekazywać błąd „na zewnątrz” bez wyjątków.

Pytanie z podstępem.

Pytanie: "Czy można wyrzucać i łapać błędy dowolnego typu, na przykład ciągi znaków lub liczby?"

Odpowiedź: Nie, w Swift można wyrzucać tylko typy, które odpowiadają protokołowi Error.

// Źle: throw "StringError" // Kompilator nie pozwoli na to // Dobrze: struct MyError: Error {} throw MyError()

Przykłady rzeczywistych błędów z powodu braku znajomości tematu.


Historia

W projekcie klienta REST API wyrzucał błąd jako ciąg znaków (throw "No data"). Kod kompilował się w JavaScript, ale po przetłumaczeniu na Swift wystąpił krytyczny błąd kompilacji.


Historia

Programista zwracał błąd przez opcjonalne wartości (return nil przy błędzie), a nie przez throw/Result. W rezultacie zabrakło szczegółów błędów, trudno było je prawidłowo przetwarzać — pojawiły się ciche błędy (Silent fails).


Historia

Analiza wykazała, że w kilku miejscach aplikacji te same błędy nie były zgrupowane w jeden typ Error. W efekcie aplikacje różnie przetwarzały podobne awarie, UI wyświetlał różne komunikaty dla jednego błędu — trudne do utrzymania i testowania.