@@ -72,21 +72,8 @@ final class CourseRepositoryImpl: CourseRepository {
7272 throw URLError ( . badServerResponse)
7373 }
7474
75- // 401 외의 코드도 명확히 분기
76- if http. statusCode == 401 {
77- if let tokens = await refreshToken ( ) {
78- tokenStorage. accessToken = tokens. accessToken
79- if let rt = tokens. refreshToken { tokenStorage. refreshToken = rt }
80- print ( " 재발급 성공 → 스트림 재연결 " )
81- await startStream ( request, continuation: continuation)
82- return
83- } else {
84- continuation. finish ( throwing: NSError ( domain: " CourseRepository " , code: 401 , userInfo: [ NSLocalizedDescriptionKey: " 토큰 재발급 실패 " ] ) )
85- return
86- }
87- } else if http. statusCode != 200 {
88- // 서버가 JSON 에러 바디를 줄 수 있으니 한번 읽어봄
89- // bytes(for:)는 스트림이므로 바디를 통째로 읽기 어렵다 → 상태만으로 에러 처리
75+ // HTTP 401 체크는 제거 (서버가 200으로 주기 때문)
76+ if http. statusCode != 200 {
9077 continuation. finish ( throwing: NSError ( domain: " CourseRepository " , code: http. statusCode, userInfo: [ NSLocalizedDescriptionKey: " SSE 연결 실패 ( \( http. statusCode) ) " ] ) )
9178 return
9279 }
@@ -100,23 +87,41 @@ final class CourseRepositoryImpl: CourseRepository {
10087 let events = parser. feed ( Data ( [ byte] ) )
10188 for event in events {
10289 guard !event. data. isEmpty, let payload = event. data. data ( using: . utf8) else { continue }
90+
91+ // 1. 데이터 내부의 에러 코드 확인 (TOK_001)
92+ if let errorCheck = try ? JSONDecoder ( ) . decode ( SSEErrorPayload . self, from: payload) ,
93+ errorCheck. responseCode == " TOK_001 " {
94+
95+ if let tokens = await refreshToken ( ) {
96+ tokenStorage. accessToken = tokens. accessToken
97+ if let rt = tokens. refreshToken { tokenStorage. refreshToken = rt }
98+ print ( " 재발급 성공 → 스트림 재연결 " )
99+ // 현재 스트림을 종료하지 않고 새 연결 시도
100+ await startStream ( request, continuation: continuation)
101+ return
102+ } else {
103+ continuation. finish ( throwing: NSError ( domain: " CourseRepository " , code: 401 , userInfo: [ NSLocalizedDescriptionKey: " 토큰 재발급 실패 " ] ) )
104+ return
105+ }
106+ }
107+
108+ // 2. 정상 데이터 디코딩
103109 do {
104110 let decoded = try JSONDecoder ( ) . decode ( CourseSearchResponse . self, from: payload)
111+ print ( " 데이터 수신: \( decoded) " )
105112 continuation. yield ( decoded)
106113 } catch {
107- // 서버가 keep-alive ping 이나 텍스트를 보낼 수 있으므로 디코드 실패는 경고만
108- print ( " SSE decode 실패: " , error, " raw: " , event. data)
114+ // 단순 텍스트나 핑 데이터인 경우 무시
115+ print ( " SSE decode 실패 (데이터 무시) : " , error, " raw: " , event. data)
109116 }
110117 }
111118 }
112119 } catch {
113- // 실제 네트워크 오류(연결 끊김 등)
114120 print ( " SSE stream read error: " , error)
115121 continuation. finish ( throwing: error)
116122 return
117123 }
118124
119- // 서버가 조용히 닫은 케이스
120125 if !receivedAny {
121126 continuation. finish ( throwing: NSError ( domain: " CourseRepository " , code: - 1 , userInfo: [ NSLocalizedDescriptionKey: " SSE에서 응답이 없습니다. " ] ) )
122127 return
@@ -182,6 +187,9 @@ final class CourseRepositoryImpl: CourseRepository {
182187 return nil
183188 }
184189 }
185-
186190}
187191
192+ struct SSEErrorPayload : Decodable {
193+ let responseCode : String ?
194+ let message : String ?
195+ }
0 commit comments