fix: API 응답 파싱 오류 수정 및 에러 처리 개선
주요 변경사항: - 창고 관리 API 응답 구조와 DTO 불일치 수정 - WarehouseLocationDto에 code, manager_phone 필드 추가 - RemoteDataSource에서 API 응답을 DTO 구조에 맞게 변환 - 회사 관리 API 응답 파싱 오류 수정 - CompanyResponse의 필수 필드를 nullable로 변경 - PaginatedResponse 구조 매핑 로직 개선 - 에러 처리 및 로깅 개선 - Service Layer에 상세 에러 로깅 추가 - Controller에서 에러 타입별 처리 - 새로운 유틸리티 추가 - ResponseInterceptor: API 응답 정규화 - DebugLogger: 디버깅 도구 - HealthCheckService: 서버 상태 확인 - 문서화 - API 통합 테스트 가이드 - 에러 분석 보고서 - 리팩토링 계획서
This commit is contained in:
@@ -4,6 +4,7 @@ import '../../../core/config/environment.dart';
|
||||
import 'interceptors/auth_interceptor.dart';
|
||||
import 'interceptors/error_interceptor.dart';
|
||||
import 'interceptors/logging_interceptor.dart';
|
||||
import 'interceptors/response_interceptor.dart';
|
||||
|
||||
/// API 클라이언트 클래스
|
||||
class ApiClient {
|
||||
@@ -18,15 +19,20 @@ class ApiClient {
|
||||
|
||||
ApiClient._internal() {
|
||||
try {
|
||||
print('[ApiClient] 초기화 시작');
|
||||
_dio = Dio(_baseOptions);
|
||||
print('[ApiClient] Dio 인스턴스 생성 완료');
|
||||
print('[ApiClient] Base URL: ${_dio.options.baseUrl}');
|
||||
print('[ApiClient] Connect Timeout: ${_dio.options.connectTimeout}');
|
||||
print('[ApiClient] Receive Timeout: ${_dio.options.receiveTimeout}');
|
||||
_setupInterceptors();
|
||||
} catch (e) {
|
||||
print('Error while creating ApiClient');
|
||||
print('Stack trace:');
|
||||
print(StackTrace.current);
|
||||
print('[ApiClient] 인터셉터 설정 완료');
|
||||
} catch (e, stackTrace) {
|
||||
print('[ApiClient] ⚠️ 에러 발생: $e');
|
||||
print('[ApiClient] Stack trace: $stackTrace');
|
||||
// 기본값으로 초기화
|
||||
_dio = Dio(BaseOptions(
|
||||
baseUrl: 'http://localhost:8080/api/v1',
|
||||
baseUrl: 'https://superport.naturebridgeai.com/api/v1',
|
||||
connectTimeout: const Duration(seconds: 30),
|
||||
receiveTimeout: const Duration(seconds: 30),
|
||||
headers: {
|
||||
@@ -35,6 +41,7 @@ class ApiClient {
|
||||
},
|
||||
));
|
||||
_setupInterceptors();
|
||||
print('[ApiClient] 기본값으로 초기화 완료');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +66,7 @@ class ApiClient {
|
||||
} catch (e) {
|
||||
// Environment가 초기화되지 않은 경우 기본값 사용
|
||||
return BaseOptions(
|
||||
baseUrl: 'http://localhost:8080/api/v1',
|
||||
baseUrl: 'https://superport.naturebridgeai.com/api/v1',
|
||||
connectTimeout: const Duration(seconds: 30),
|
||||
receiveTimeout: const Duration(seconds: 30),
|
||||
headers: {
|
||||
@@ -77,13 +84,7 @@ class ApiClient {
|
||||
void _setupInterceptors() {
|
||||
_dio.interceptors.clear();
|
||||
|
||||
// 인증 인터셉터
|
||||
_dio.interceptors.add(AuthInterceptor());
|
||||
|
||||
// 에러 처리 인터셉터
|
||||
_dio.interceptors.add(ErrorInterceptor());
|
||||
|
||||
// 로깅 인터셉터 (개발 환경에서만)
|
||||
// 로깅 인터셉터 (개발 환경에서만) - 가장 먼저 추가하여 모든 요청/응답을 로깅
|
||||
try {
|
||||
if (Environment.enableLogging && kDebugMode) {
|
||||
_dio.interceptors.add(LoggingInterceptor());
|
||||
@@ -94,6 +95,15 @@ class ApiClient {
|
||||
_dio.interceptors.add(LoggingInterceptor());
|
||||
}
|
||||
}
|
||||
|
||||
// 인증 인터셉터 - 요청에 토큰 추가 및 401 처리
|
||||
_dio.interceptors.add(AuthInterceptor(_dio));
|
||||
|
||||
// 응답 정규화 인터셉터 - 성공 응답을 일관된 형식으로 변환
|
||||
_dio.interceptors.add(ResponseInterceptor());
|
||||
|
||||
// 에러 처리 인터셉터 - 마지막에 추가하여 모든 에러를 캐치
|
||||
_dio.interceptors.add(ErrorInterceptor());
|
||||
}
|
||||
|
||||
/// 토큰 업데이트
|
||||
@@ -133,6 +143,9 @@ class ApiClient {
|
||||
ProgressCallback? onSendProgress,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
}) {
|
||||
print('[ApiClient] POST 요청 시작: $path');
|
||||
print('[ApiClient] 요청 데이터: $data');
|
||||
|
||||
return _dio.post<T>(
|
||||
path,
|
||||
data: data,
|
||||
@@ -141,7 +154,18 @@ class ApiClient {
|
||||
cancelToken: cancelToken,
|
||||
onSendProgress: onSendProgress,
|
||||
onReceiveProgress: onReceiveProgress,
|
||||
);
|
||||
).then((response) {
|
||||
print('[ApiClient] POST 응답 수신: ${response.statusCode}');
|
||||
return response;
|
||||
}).catchError((error) {
|
||||
print('[ApiClient] POST 에러 발생: $error');
|
||||
if (error is DioException) {
|
||||
print('[ApiClient] DioException 타입: ${error.type}');
|
||||
print('[ApiClient] DioException 메시지: ${error.message}');
|
||||
print('[ApiClient] DioException 에러: ${error.error}');
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/// PUT 요청
|
||||
|
||||
Reference in New Issue
Block a user