주요 변경사항: - 창고 관리 API 응답 구조와 DTO 불일치 수정 - WarehouseLocationDto에 code, manager_phone 필드 추가 - RemoteDataSource에서 API 응답을 DTO 구조에 맞게 변환 - 회사 관리 API 응답 파싱 오류 수정 - CompanyResponse의 필수 필드를 nullable로 변경 - PaginatedResponse 구조 매핑 로직 개선 - 에러 처리 및 로깅 개선 - Service Layer에 상세 에러 로깅 추가 - Controller에서 에러 타입별 처리 - 새로운 유틸리티 추가 - ResponseInterceptor: API 응답 정규화 - DebugLogger: 디버깅 도구 - HealthCheckService: 서버 상태 확인 - 문서화 - API 통합 테스트 가이드 - 에러 분석 보고서 - 리팩토링 계획서
99 lines
2.8 KiB
Dart
99 lines
2.8 KiB
Dart
import 'package:dio/dio.dart';
|
|
import '../core/config/environment.dart';
|
|
import '../data/datasources/remote/api_client.dart';
|
|
|
|
/// API 헬스체크 테스트를 위한 서비스
|
|
class HealthCheckService {
|
|
final ApiClient _apiClient;
|
|
|
|
HealthCheckService({ApiClient? apiClient})
|
|
: _apiClient = apiClient ?? ApiClient();
|
|
|
|
/// 헬스체크 API 호출
|
|
Future<Map<String, dynamic>> checkHealth() async {
|
|
try {
|
|
print('=== 헬스체크 시작 ===');
|
|
print('API Base URL: ${Environment.apiBaseUrl}');
|
|
print('Full URL: ${Environment.apiBaseUrl}/health');
|
|
|
|
final response = await _apiClient.get('/health');
|
|
|
|
print('응답 상태 코드: ${response.statusCode}');
|
|
print('응답 데이터: ${response.data}');
|
|
|
|
return {
|
|
'success': true,
|
|
'data': response.data,
|
|
'statusCode': response.statusCode,
|
|
};
|
|
} on DioException catch (e) {
|
|
print('=== DioException 발생 ===');
|
|
print('에러 타입: ${e.type}');
|
|
print('에러 메시지: ${e.message}');
|
|
print('에러 응답: ${e.response?.data}');
|
|
print('에러 상태 코드: ${e.response?.statusCode}');
|
|
|
|
// CORS 에러인지 확인
|
|
if (e.type == DioExceptionType.connectionError ||
|
|
e.type == DioExceptionType.unknown) {
|
|
print('⚠️ CORS 또는 네트워크 연결 문제일 가능성이 있습니다.');
|
|
}
|
|
|
|
return {
|
|
'success': false,
|
|
'error': e.message ?? '알 수 없는 에러',
|
|
'errorType': e.type.toString(),
|
|
'statusCode': e.response?.statusCode,
|
|
'responseData': e.response?.data,
|
|
};
|
|
} catch (e) {
|
|
print('=== 일반 에러 발생 ===');
|
|
print('에러: $e');
|
|
|
|
return {
|
|
'success': false,
|
|
'error': e.toString(),
|
|
};
|
|
}
|
|
}
|
|
|
|
/// 직접 Dio로 테스트 (인터셉터 없이)
|
|
Future<Map<String, dynamic>> checkHealthDirect() async {
|
|
try {
|
|
print('=== 직접 Dio 헬스체크 시작 ===');
|
|
|
|
final dio = Dio(BaseOptions(
|
|
baseUrl: Environment.apiBaseUrl,
|
|
connectTimeout: const Duration(seconds: 10),
|
|
receiveTimeout: const Duration(seconds: 10),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
},
|
|
));
|
|
|
|
// 로깅 인터셉터만 추가
|
|
dio.interceptors.add(LogInterceptor(
|
|
requestBody: true,
|
|
responseBody: true,
|
|
requestHeader: true,
|
|
responseHeader: true,
|
|
error: true,
|
|
));
|
|
|
|
final response = await dio.get('/health');
|
|
|
|
return {
|
|
'success': true,
|
|
'data': response.data,
|
|
'statusCode': response.statusCode,
|
|
};
|
|
} catch (e) {
|
|
print('직접 Dio 에러: $e');
|
|
return {
|
|
'success': false,
|
|
'error': e.toString(),
|
|
};
|
|
}
|
|
}
|
|
} |