J
[Combine] 에러 처리: tryMap, catch, replaceError 본문
Combine에서의 에러 처리: tryMap, catch, replaceError
Combine을 사용하다 보면 네트워크 요청, JSON 파싱, 사용자 입력 등 다양한 상황에서 에러가 발생할 수 있습니다.
Combine에서는 스트림 중간에 에러가 발생하면 스트림이 종료되므로, 이를 적절히 처리할 수 있는 에러 핸들링 기법이 중요합니다.
1. 에러가 있는 Publisher vs 없는 Publisher
Combine에서는 Publisher가 에러를 발생시킬 수 있는지 여부에 따라 타입이 다릅니다.
// 에러를 발생시키지 않는 Publisher
let noErrorPublisher = Just("Hello") // 타입: Just<String>
// 에러를 발생시킬 수 있는 Publisher
let errorPublisher = Fail<String, URLError>(error: URLError(.badURL))
- Publisher의 제네릭 형식은 <Output, Failure> 형태
- Failure 타입이 Never이면 에러가 발생하지 않음
- 에러가 발생할 수 있으면, Failure가 Error 또는 그 하위 타입
2. tryMap – 에러를 던질 수 있는 변환 처리
map은 단순한 변환만 가능하지만, tryMap은 변환 도중 에러를 throw할 수 있는 로직을 포함할 수 있습니다.
let values = ["1", "2", "Three", "4"]
values.publisher
.tryMap { str -> Int in
guard let intVal = Int(str) else {
throw NSError(domain: "InvalidNumber", code: -1)
}
return intVal
}
.sink(
receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("에러 발생: \(error)")
case .finished:
print("완료")
}
},
receiveValue: { value in
print("값: \(value)")
}
)
값: 1
값: 2
에러 발생: Error Domain=InvalidNumber Code=-1 ...
- tryMap 안에서 에러가 발생하면 스트림이 즉시 종료
3. catch – 에러를 감지하고 다른 Publisher로 대체
catch는 에러가 발생했을 때, 다른 Publisher로 스트림을 이어가도록 만들어줍니다.
let publisher = Fail<String, Error>(error: NSError(domain: "Error", code: -1))
publisher
.catch { error in
Just("기본값으로 대체") // 새 Publisher 반환
}
.sink { value in
print("결과: \(value)")
}
결과: 기본값으로 대체
- 에러가 발생해도 스트림이 완료되지 않고 계속 진행 가능
- 실무에서 네트워크 실패 시 대체 로직에 자주 사용됨
4. replaceError – 에러를 특정 값으로 대체하고 종료
replaceError(with:)는 에러 발생 시 특정 값을 리턴하고 스트림을 종료합니다.
catch보다 간단한 대안입니다.
let publisher = Fail<String, Error>(error: NSError(domain: "Fail", code: -1))
publisher
.replaceError(with: "에러 발생 → 기본값 사용")
.sink { value in
print("출력: \(value)")
}
출력: 에러 발생 → 기본값 사용
- 단순히 에러를 무시하고 기본 값으로 대체 후 종료
언제 어떤 걸 써야 할까?
목적 | 사용 연산자 |
에러를 던지는 변환 처리 | tryMap |
에러 발생 시 새로운 스트림으로 전환 | catch |
에러 발생 시 값 하나로 대체 후 종료 | replaceError |
정리
연산자 | 기능 |
tryMap | 변환 중 에러 발생 가능 |
catch | 에러 발생 시 다른 Publisher로 대체 |
replaceError(with:) | 에러 발생 시 특정 값으로 대체 후 스트림 종료 |
Combine에서는 에러가 발생하면 기본적으로 스트림이 멈추기 때문에, 상황에 맞는 에러 처리 로직을 꼭 작성해두는 것이 중요합니다.
'iOS > Combine' 카테고리의 다른 글
[Combine] Scheduler와 비동기 처리 이해하기 (0) | 2025.04.08 |
---|---|
[Combine] Subject와 @Published... SwiftUI 연동까지 (0) | 2025.04.07 |
[Combine] Publisher, Subscriber, Operator, Cancellable (0) | 2025.04.07 |
[Combine] Network 통신 (Upbit API 예제 포함) (0) | 2024.11.12 |