feat: ConnectAI structural hardening and retrieval precision improvements

This commit is contained in:
g1nation
2026-05-05 21:37:45 +09:00
parent c2f17cfb03
commit 466e9e4d5f
17 changed files with 424 additions and 160 deletions
+8 -24
View File
@@ -1,18 +1,12 @@
import { logInfo, logError } from '../utils';
export enum ApiErrorType {
AUTH_FAILURE = 'AUTH_FAILURE',
RATE_LIMIT = 'RATE_LIMIT',
NETWORK_TIMEOUT = 'NETWORK_TIMEOUT',
SERVER_ERROR = 'SERVER_ERROR',
UNKNOWN = 'UNKNOWN'
}
import { ErrorType } from '../types/interfaces';
import { ErrorClassifier } from './engine';
export interface ApiResponse<T> {
success: boolean;
data?: T;
error?: {
type: ApiErrorType;
type: ErrorType;
message: string;
isRecoverable: boolean;
};
@@ -33,9 +27,6 @@ export class ExternalApiHandler {
return false; // 현재는 기본적으로 수동 개입 필요로 처리
}
/**
* 지능형 요청 래퍼 (Resilient Fetch)
*/
public static async request<T>(
call: () => Promise<T>,
context: string
@@ -45,25 +36,18 @@ export class ExternalApiHandler {
return { success: true, data };
} catch (error: any) {
logError(`[ApiHandler] [${context}] 호출 실패:`, error);
const errorType = this.classifyError(error);
// ErrorClassifier를 통해 시스템 통합 분류 적용
const { type, rule } = ErrorClassifier.classify(error);
return {
success: false,
error: {
type: errorType,
type,
message: error.message,
isRecoverable: errorType === ApiErrorType.NETWORK_TIMEOUT || errorType === ApiErrorType.RATE_LIMIT
isRecoverable: type === ErrorType.TRANSIENT || type === ErrorType.AUTH_FAILURE
}
};
}
}
private static classifyError(error: any): ApiErrorType {
const msg = error.message || '';
if (msg.includes('401') || msg.includes('unauthorized')) return ApiErrorType.AUTH_FAILURE;
if (msg.includes('429') || msg.includes('rate limit')) return ApiErrorType.RATE_LIMIT;
if (msg.includes('timeout') || msg.includes('ETIMEDOUT')) return ApiErrorType.NETWORK_TIMEOUT;
if (msg.includes('500') || msg.includes('502') || msg.includes('503')) return ApiErrorType.SERVER_ERROR;
return ApiErrorType.UNKNOWN;
}
}