77
88import Foundation
99import OSLog
10+ import Combine
1011
1112// 실제 네트워크 요청을 처리하는 클래스
1213
@@ -16,6 +17,7 @@ import OSLog // LogMacro가 사용 불가능한 경우 (더 낮은 버전)
1617public class AsyncProvider < T: TargetType > {
1718 private let session : URLSession
1819 private let maxRetryCount = 3
20+ private let retryDelay : TimeInterval = 2.0 // 재시도 간격 (2초)
1921
2022 public init ( session: URLSession = . shared) {
2123 self . session = session
@@ -36,52 +38,51 @@ public class AsyncProvider<T: TargetType> {
3638 decodeTo type: D . Type ,
3739 retryCount: Int
3840 ) async throws -> D {
39- let ( data, response) = try await session. data ( for: request)
40-
41- guard let httpResponse = response as? HTTPURLResponse else {
42- Log . error ( " No HTTP response received " )
43- throw DataError . noData
44- }
45-
46- switch httpResponse. statusCode {
47- case 200 ... 299 :
48- // 성공 응답 처리
49- return try data. decoded ( as: D . self)
50-
51- case 400 :
52- Log . error ( " Bad Request (400) for URL: \( request. url? . absoluteString ?? " No URL " ) " )
53- throw DataError . customError ( " Bad Request (400) " )
54-
55- case 404 :
56- Log . error ( " Not Found (404) for URL: \( request. url? . absoluteString ?? " No URL " ) " )
57- throw DataError . customError ( " Not Found (404) " )
58-
59- case 500 :
60- Log . error ( " Internal Server Error (500), attempting to decode response (Retry Count: \( retryCount + 1 ) ) " )
41+ do {
42+ let ( data, response) = try await session. data ( for: request)
43+ guard let httpResponse = response as? HTTPURLResponse else {
44+ Log . error ( " No HTTP response received " )
45+ throw DataError . noData
46+ }
6147
62- if retryCount < maxRetryCount {
63- do {
64- // 500 상태 코드일 때도 데이터를 디코딩 시도
65- return try decodeErrorResponseData ( data: data, decodeTo: D . self)
66- } catch {
67- Log . error ( " Decoding failed for 500 error response, retrying... (Retry Count: \( retryCount + 1 ) ) " )
48+ switch httpResponse. statusCode {
49+ case 200 ... 299 :
50+ // 성공 응답 처리
51+ return try data. decoded ( as: D . self)
52+
53+ case 400 :
54+ Log . error ( " Bad Request (400) for URL: \( request. url? . absoluteString ?? " No URL " ) " )
55+ throw DataError . customError ( " Bad Request (400) " )
56+
57+ case 404 :
58+ Log . error ( " Not Found (404) for URL: \( request. url? . absoluteString ?? " No URL " ) " )
59+ throw DataError . customError ( " Not Found (404) " )
60+
61+ case 500 :
62+ Log . error ( " Internal Server Error (500), attempting to decode response (Retry Count: \( retryCount + 1 ) ) " )
63+ // 500 에러일 때 데이터를 제네릭 D 타입으로 디코딩 시도
64+ if retryCount < maxRetryCount {
65+ // 대기 후 재시도
66+ try await Task . sleep ( nanoseconds: UInt64 ( retryDelay * 1_000_000_000 ) ) // 대기 시간
6867 return try await executeWithRetry ( request: request, decodeTo: type, retryCount: retryCount + 1 )
69- }
70- } else {
71- Log . error ( " Failed after 3 retries for 500 error response " )
72-
73- // 500 상태 코드에서 실패할 경우에도 ErrorResponse를 처리하려고 시도
74- if let errorResponse = try ? decodeErrorResponseData ( data: data, decodeTo: D . self) {
75- Log . debug ( " Decoded ErrorResponse with 500 status code " )
76- return errorResponse
7768 } else {
69+ Log . error ( " Failed after 3 retries for 500 error response " )
7870 throw DataError . unhandledStatusCode ( httpResponse. statusCode)
7971 }
80- }
8172
82- default :
83- Log . error ( " Unhandled status code: \( httpResponse. statusCode) for URL: \( request. url? . absoluteString ?? " No URL " ) " )
84- throw DataError . unhandledStatusCode ( httpResponse. statusCode)
73+ default :
74+ Log . error ( " Unhandled status code: \( httpResponse. statusCode) for URL: \( request. url? . absoluteString ?? " No URL " ) " )
75+ throw DataError . unhandledStatusCode ( httpResponse. statusCode)
76+ }
77+ } catch {
78+ Log . error ( " Network request failed with error: \( error. localizedDescription) " )
79+ if retryCount < maxRetryCount {
80+ // 대기 후 재시도
81+ try await Task . sleep ( nanoseconds: UInt64 ( retryDelay * 1_000_000_000 ) ) // 대기 시간
82+ return try await executeWithRetry ( request: request, decodeTo: type, retryCount: retryCount + 1 )
83+ } else {
84+ throw error // 재시도 횟수를 초과한 경우 원래 에러를 던짐
85+ }
8586 }
8687 }
8788
0 commit comments