Project/HiddenGem

🔨 API 호출 함수 손 보기 (에러 처리 과정 적용)

밤새는 탐험가89 2025. 4. 25. 12:03

✅ 에러 처리 미 포함 

func getStoreCategories() async throws -> [StoreCategory] {
    var components = URLComponents(string: "\(Constants.baseURLString)/categoryCode1")

    components?.queryItems = [
        URLQueryItem(name: "serviceKey", value: Constants.api_key),
        URLQueryItem(name: "numOfRows", value: "10"),
        URLQueryItem(name: "pageNo", value: "1"),
        URLQueryItem(name: "MobileOS", value: "ETC"),
        URLQueryItem(name: "MobileApp", value: "AppTest"),
        URLQueryItem(name: "contentTypeId", value: "39"),
        URLQueryItem(name: "cat1", value: "A05"),
        URLQueryItem(name: "cat2", value: "A0502"),
        URLQueryItem(name: "_type", value: "json")
    ]

    if let encodedQuery = components?.percentEncodedQuery?.replacingOccurrences(of: "%25", with: "%") {
        components?.percentEncodedQuery = encodedQuery
    }

    guard let url = components?.url else {
        throw URLError(.badURL)
    }

    let (data, _) = try await URLSession.shared.data(from: url)
    let decoded = try JSONDecoder().decode(CategoryResponse.self, from: data)

    return decoded.response.body.items.item
}

 

 

🔨 각 로직 별로 에러 처리를 세분화하여 print() 를 통해 에러 위치와 에러 내용을 정리해보겠습니다. 

 

  • URLComponents → URL 생성 실패
  • URLSession.data → 네트워크 에러
  • JSONDecoder.decode → 디코딩 실패

 

✅ 개선된 getStoreCategories() with 디버깅용 에러 로그

func getStoreCategories() async throws -> [StoreCategory] {
    var components = URLComponents(string: "\(Constants.baseURLString)/categoryCode1")
    
    components?.queryItems = [
        URLQueryItem(name: "serviceKey", value: Constants.api_key),
        URLQueryItem(name: "numOfRows", value: "10"),
        URLQueryItem(name: "pageNo", value: "1"),
        URLQueryItem(name: "MobileOS", value: "ETC"),
        URLQueryItem(name: "MobileApp", value: "AppTest"),
        URLQueryItem(name: "contentTypeId", value: "39"),
        URLQueryItem(name: "cat1", value: "A05"),
        URLQueryItem(name: "cat2", value: "A0502"),
        URLQueryItem(name: "_type", value: "json")
    ]
    
    // URL 인코딩 오류 방지 (필요 시만)
    if let encodedQuery = components?.percentEncodedQuery?.replacingOccurrences(of: "%25", with: "%") {
        components?.percentEncodedQuery = encodedQuery
    }
    
    guard let url = components?.url else {
        print("❌ URL 생성 실패: \(String(describing: components?.string))")
        throw URLError(.badURL)
    }
    
    print("📡 호출할 URL: \(url.absoluteString)")
    
    do {
        let (data, response) = try await URLSession.shared.data(from: url)

        // 상태 코드 디버깅
        if let httpResponse = response as? HTTPURLResponse {
            print("📦 상태 코드: \(httpResponse.statusCode)")
        }

        let decoded = try JSONDecoder().decode(CategoryResponse.self, from: data)
        print("✅ 디코딩 성공, 항목 개수: \(decoded.response.body.items.item.count)개")
        return decoded.response.body.items.item

    } catch let decodingError as DecodingError {
        print("❌ 디코딩 오류: \(decodingError)")
        throw decodingError
    } catch {
        print("❌ 네트워크 요청 또는 기타 오류: \(error.localizedDescription)")
        throw error
    }
}

 

🧠 이렇게 하면 좋은 점

  • 호출 URL을 콘솔에 출력해서 정확히 어떤 URL이 호출됐는지 확인 가능
  • 응답 상태코드 (200, 400, 500 등)로 서버 문제인지 클라이언트 문제인지 구분 가능
  • DecodingError를 별도로 잡아서 디코딩 구조 문제인지 확실히 확인 가능