[swift] 에러 핸들링을 위한 커스텀 에러 타입 정의 방법

에러 핸들링은 모든 앱이나 시스템에서 중요한 부분입니다. Swift에서는 에러를 표현하기 위해 커스텀 에러 타입을 정의하는 것이 좋은 방법입니다. 이 포스트에서는 Swift에서 커스텀 에러 타입을 어떻게 정의하는지 알아보겠습니다.

1. 에러 타입 정의

먼저, 커스텀 에러 타입을 정의하기 위해 Error 프로토콜을 준수하는 enum 또는 struct를 선언합니다.

enum NetworkError: Error {
    case noInternetConnection
    case serverNotFound
    case requestTimeout
}

위의 예시에서 NetworkError는 커스텀 에러 타입이며 Error 프로토콜을 준수하고 있습니다. 각 case는 특정한 상황에서 발생하는 에러를 나타냅니다.

2. 에러 던지기 및 처리하기

이제 커스텀 에러를 발생시키고 처리하는 방법에 대해 알아보겠습니다.

func fetchDataFromServer() throws {
    guard isInternetAvailable else {
        throw NetworkError.noInternetConnection
    }
    
    guard serverIsReachable else {
        throw NetworkError.serverNotFound
    }

    // 서버로부터 데이터를 가져오는 동작 수행
}

위의 예시에서 fetchDataFromServer 함수는 에러를 던질 수 있는 함수로 정의되어 있습니다. throw 키워드를 사용하여 특정 조건일 때 NetworkError 타입의 에러를 던집니다.

이를 호출하는 측에서는 do-catch 블록을 사용하여 에러를 처리할 수 있습니다.

do {
    try fetchDataFromServer()
    // 서버로부터 가져온 데이터 처리
} catch NetworkError.noInternetConnection {
    print("인터넷 연결이 없습니다.")
} catch NetworkError.serverNotFound {
    print("서버를 찾을 수 없습니다.")
} catch {
    print("알 수 없는 에러가 발생했습니다.")
}

3. 보다 복잡한 상황 다루기

커스텀 에러 타입을 사용하면, 보다 복잡한 상황에서도 유용하게 사용할 수 있습니다. 예를 들어, 연관 값을 통해 더 많은 정보를 담아 에러를 처리할 수 있습니다.

enum DataError: Error {
    case invalidData(reason: String)
    case dataNotFound(key: String)
}

func processData(_ data: Data?) throws {
    guard let validData = data else {
        throw DataError.invalidData(reason: "유효하지 않은 데이터입니다.")
    }
    
    guard let requiredData = validData["required"] else {
        throw DataError.dataNotFound(key: "required")
    }
    
    // 데이터 처리 로직
}

위의 예시에서 DataError는 연관 값으로 추가적인 정보를 전달하는 방법을 나타냅니다.

에러 핸들링은 프로그래밍에서 중요한 부분이며, 커스텀 에러 타입을 정의하여 보다 효율적으로 에러를 다룰 수 있습니다.

에러 핸들링과 관련된 자세한 정보는 Swift 공식 문서를 참고하세요.