Error Handling

인터넷이 연결되어 있지 않거나, 숫자를 입력해야하는데 특수문자가 끼게 되는 경우, API나 HTTP 에러가 나는 경우 등

에러가 날 수 있는 상황은 다양하다.

 

이를 대비해 다음과 같이 catch 구문을 써서 error 를 throw 할 수도 있고,

 

 

단순히 재요청의 의미로 retry 할 수도 있을 것이다.

 

 

 

이제 이들을 하나씩 차례로 살펴보도록 하자.

 

Catch Error

API를 던졌는데 HTTPStatus code가 200번대가 아닌 경우 대부분 에러코드이다.

만약 에러코드를 반환받은 상황이라고 한다면, 우리는 이것을 RxCococaURLError를 가지고 해결할 수 있다.

 

아래는 http통신을 통해 API를 받아오는 코드인데, if 200..<300 부터 코드를 보면 statusCode가 200~299인 경우에만 data를 decode하고 그렇지 않은 경우에는 Error를 던지고 있다. 이 때 쓰이는 것이 RxCocoaURLError.httpRequestFailed 이다.

static func load<T: Decodable>(resource: Resource<T>) -> Observable<T?> {

        return Observable.just(resource.url)
            .flatMap { url -> Observable<(response: HTTPURLResponse, data: Data)> in
                let request = URLRequest(url: url)
                return URLSession.shared.rx.response(request: request)
            }.map { response, data -> T in
                if 200..<300 ~= response.statusCode { //~=: inside range(범위)
                    return try JSONDecoder().decode(T.self, from: data)
                } else {
                    throw RxCocoaURLError.httpRequestFailed(response: response, data: data)
                }
            }.asObservable()
    }

 

이 때 throw는 했는데 catch하는 부분은 없으니 catch하는 부분도 살펴보자.

thrown error를 catch하는 것은 .catchError 를 통해 할 수 있으며, 아래처럼 사용할 수 있다.

 

 let search = URLRequest.load(resource: resource)
            .observeOn(MainScheduler.instance)
            .catchError { error in
                print(error.localizedDescription)
                return Observable.just(WeatherResult.empty)
            }.asDriver(onErrorJustReturn: WeatherResult.empty)

 

Retry

인터넷이 끊긴 경우 계속 다시 신청할 수 있다.

물론 무한대로 신청하는 것은 좋은 생각이 아니지만 몇 번 정도는 리트라이 할 수 있을 것이다.

이를 고려해 리트라이는 애초에 횟수를 지정하여 사용한다.

리트라이의 예제를 살펴보자.

 

        let search = URLRequest.load(resource: resource)
            .observeOn(MainScheduler.instance)
            .retry(3)
            .catchError { error in
                print(error.localizedDescription)
                return Observable.just(WeatherResult.empty)
            }.asDriver(onErrorJustReturn: WeatherResult.empty)

 

예제를 보면 .retry(3) 이라고 되어 있는데, 이는 총 3번을 재시도한다는 것이다.

3번 요청 이후에는 .retry(3)이 무시되며, 

우리가 throw한 error가 catchError로 넘어가게 된다.

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기
// custom