Files
auto-trade/lib/kis/error-codes.ts

189 lines
8.2 KiB
TypeScript
Raw Normal View History

2026-02-26 09:05:17 +09:00
/**
* @file lib/kis/error-codes.ts
* @description KIS FAQ (msg_cd) .
* @see https://apiportal.koreainvestment.com/faq-error-code 한국투자증권 공식 오류코드 기준
*/
export const KIS_ERROR_CODE_REFERENCE_URL =
"https://apiportal.koreainvestment.com/faq-error-code";
const KIS_ERROR_CODE_MESSAGE_MAP = {
EGW00001: "일시적 오류가 발생했습니다.",
EGW00002: "서버 에러가 발생했습니다.",
EGW00003: "접근이 거부되었습니다.",
EGW00004: "권한을 부여받지 않은 고객입니다.",
EGW00101: "유효하지 않은 요청입니다.",
EGW00102: "AppKey는 필수입니다.",
EGW00103: "유효하지 않은 AppKey입니다.",
EGW00104: "AppSecret은 필수입니다.",
EGW00105: "유효하지 않은 AppSecret입니다.",
EGW00106: "redirect_uri는 필수입니다.",
EGW00107: "유효하지 않은 redirect_uri입니다.",
EGW00108: "유효하지 않은 서비스구분(service)입니다.",
EGW00109: "scope는 필수입니다.",
EGW00110: "유효하지 않은 scope 입니다.",
EGW00111: "유효하지 않은 state 입니다.",
EGW00112: "유효하지 않은 grant 입니다.",
EGW00113: "응답구분(response_type)은 필수입니다.",
EGW00114: "지원하지 않는 응답구분(response_type)입니다.",
EGW00115: "권한부여 타입(grant_type)은 필수입니다.",
EGW00116: "지원하지 않는 권한부여 타입(grant_type)입니다.",
EGW00117: "지원하지 않는 토큰 타입(token_type)입니다.",
EGW00118: "유효하지 않은 code 입니다.",
EGW00119: "code를 찾을 수 없습니다.",
EGW00120: "기간이 만료된 code 입니다.",
EGW00121: "유효하지 않은 token 입니다.",
EGW00122: "token을 찾을 수 없습니다.",
EGW00123: "기간이 만료된 token 입니다.",
EGW00124: "유효하지 않은 session_key 입니다.",
EGW00125: "session_key를 찾을 수 없습니다.",
EGW00126: "기간이 만료된 session_key 입니다.",
EGW00127: "제휴사번호(corpno)는 필수입니다.",
EGW00128: "계좌번호(acctno)는 필수입니다.",
EGW00129: "HTS_ID는 필수입니다.",
EGW00130: "유효하지 않은 유저(user)입니다.",
EGW00131: "유효하지 않은 hashkey입니다.",
EGW00132: "Content-Type이 유효하지 않습니다.",
EGW00201: "초당 거래건수를 초과하였습니다.",
EGW00202: "GW라우팅 중 오류가 발생했습니다.",
EGW00203: "OPS라우팅 중 오류가 발생했습니다.",
EGW00204: "Internal Gateway 인스턴스를 잘못 입력했습니다.",
EGW00205: "credentials_type이 유효하지 않습니다.(Bearer)",
EGW00206: "API 사용 권한이 없습니다.",
EGW00207: "IP 주소가 없거나 유효하지 않습니다.",
EGW00208: "고객유형(custtype)이 유효하지 않습니다.",
EGW00209: "일련번호(seq_no)가 유효하지 않습니다.",
EGW00210: "법인고객의 경우 모의투자를 이용할 수 없습니다.",
EGW00211: "고객명(personalname)은 필수 입니다.",
EGW00212: "휴대전화번호(personalphone)는 필수 입니다.",
EGW00213: "제휴사명(corpname)은 필수 입니다. / 모의투자 tr이 아닙니다.",
EGW00300: "Gateway 라우팅 오류가 발생했습니다.",
EGW00301: "연결 시간이 초과되었습니다. 직전 거래를 반드시 확인하세요.",
EGW00302: "거래시간이 초과되었습니다. 직전 거래를 반드시 확인하세요.",
EGW00303: "법인고객에게 허용되지 않은 IP접근입니다.",
EGW00304:
"고객식별키(법인 personalSeckey, 개인 appSecret)가 유효하지 않습니다.",
OPSQ0001: "호출 전처리 오류 입니다.",
OPSQ0002: "없는 서비스 코드 입니다.",
OPSQ0003: "호출 오류 입니다.",
OPSQ0004: "호출 후처리 오류 입니다.",
OPSQ0005: "호출 후처리 오류 입니다.",
OPSQ0006: "호출 후처리 오류 입니다.",
OPSQ0007: "호출 후처리(헤더설정) 오류 입니다.",
OPSQ0008: "호출 후처리(MCI전송) 오류 입니다.",
OPSQ0009: "호출 후처리(MCI수신) 오류 입니다.",
OPSQ0010: "호출 결과처리(리소스 부족) 오류 입니다.",
OPSQ0011: "호출 결과처리(리소스 부족) 오류 입니다.",
OPSQ1002: "세션 연결 오류.",
OPSQ2000: "ERROR : INPUT INVALID_CHECK_ACNO",
OPSQ2001: "ERROR : INPUT INVALID_CHECK_MRKT_DIV_CODE",
OPSQ2002: "ERROR : INPUT INVALID_CHECK_FIELD_LENGTH",
OPSQ2003: "ERROR : SET_MCI_SEND_DATA",
OPSQ3001: "ERROR : RESPONSE_ADDITEMTOOBJECT",
OPSQ3002: "ERROR : GET_CALL_PARAM_MCI_SEND_DATA_LEN",
OPSQ3004: "ERROR : OUT_STRING_ARRAY ALLOC FAILED",
OPSQ9995: "JSON PARSING ERROR : body not found",
OPSQ9996: "JSON PARSING ERROR : header not found",
OPSQ9997: "JSON PARSING ERROR : invalid json format",
OPSQ9998: "JSON PARSING ERROR : seq_no not found",
OPSQ9999: "JSON PARSING ERROR : tr_id not found",
OPSP0000: "SUBSCRIBE SUCCESS",
OPSP0001: "UNSUBSCRIBE SUCCESS",
OPSP0002: "ALREADY IN SUBSCRIBE",
OPSP0003: "UNSUBSCRIBE ERROR(not found!)",
OPSP0007: "SUBSCRIBE INTERNAL ERROR",
OPSP0008: "MAX SUBSCRIBE OVER",
OPSP0009: "SUBSCRIBE ERROR : mci send failed",
OPSP0010: "SUBSCRIBE WARNNING : invalid appkey",
OPSP0011: "invalid approval(appkey) : NOT FOUND",
OPSP8991: "SUBSCRIBE ERROR : invalid tr_id",
OPSP8992: "SUBSCRIBE ERROR : invalid tr_key",
OPSP8993: "JSON PARSING ERROR : invalid tr_key",
OPSP8994: "JSON PARSING ERROR : personalseckey not found",
OPSP8995: "JSON PARSING ERROR : appsecret not found",
OPSP8996: "ALREADY IN USE appkey",
OPSP8997: "JSON PARSING ERROR : invalid tr_type",
OPSP8998: "JSON PARSING ERROR : invalid custtype",
OPSP8999: "resource not available (ALLOC_CALL_PARAM)",
OPSP9990: "JSON PARSING ERROR : tr_key not found",
OPSP9991: "JSON PARSING ERROR : input not found",
OPSP9992: "JSON PARSING ERROR : body not found",
OPSP9993: "JSON PARSING ERROR : internal error",
OPSP9994: "JSON PARSING ERROR : INVALID appkey",
OPSP9995: "JSON PARSING ERROR : resource not available",
OPSP9996: "JSON PARSING ERROR : appkey",
OPSP9997: "JSON PARSING ERROR : custtype not found",
OPSP9998: "JSON PARSING ERROR : header not found",
OPSP9999: "JSON PARSING ERROR : invalid json format",
} as const;
export interface KisErrorGuide {
code: string;
message: string;
referenceUrl: string;
}
interface BuildKisErrorDetailParams {
message?: string;
msgCode?: string;
extraMessages?: Array<string | undefined>;
}
function normalizeKisErrorCode(msgCode?: string) {
return msgCode?.trim().toUpperCase() ?? "";
}
/**
* @description KIS msg_cd를 FAQ .
* @param msgCode KIS msg_cd
* @returns // URL . null
* @see lib/kis/client.ts kisGet/kisPost
* @see features/kis-realtime/stores/kisWebSocketStore.ts
*/
export function getKisErrorGuide(msgCode?: string): KisErrorGuide | null {
const code = normalizeKisErrorCode(msgCode);
if (!code) return null;
const message =
KIS_ERROR_CODE_MESSAGE_MAP[
code as keyof typeof KIS_ERROR_CODE_MESSAGE_MAP
];
if (!message) return null;
return {
code,
message,
referenceUrl: KIS_ERROR_CODE_REFERENCE_URL,
};
}
/**
* @description KIS (msg1/msg_cd/) .
* @param params
* @returns
* @see lib/kis/token.ts buildTokenIssueDetail /
* @see lib/kis/approval.ts issueKisApprovalKey
*/
export function buildKisErrorDetail({
message,
msgCode,
extraMessages = [],
}: BuildKisErrorDetailParams) {
const tokens = new Set<string>();
for (const raw of [...extraMessages, message]) {
const normalized = raw?.trim();
if (normalized) tokens.add(normalized);
}
const guide = getKisErrorGuide(msgCode);
const normalizedCode = normalizeKisErrorCode(msgCode);
if (guide) {
tokens.add(`${guide.code} (${guide.message})`);
} else if (normalizedCode) {
tokens.add(normalizedCode);
}
return [...tokens].join(" / ");
}