Files
vexplor_dev/backend-node/src/utils/pgErrorUtil.ts

81 lines
2.7 KiB
TypeScript
Raw Normal View History

import { query } from "../database/db";
/**
* PostgreSQL
* table_type_columns의 column_label을
*/
export async function formatPgError(
error: any,
companyCode?: string
): Promise<string> {
if (!error || !error.code) {
return error?.message || "데이터 처리 중 오류가 발생했습니다.";
}
switch (error.code) {
case "23502": {
// not_null_violation
const colName = error.column || "";
const tblName = error.table || "";
if (colName && tblName && companyCode) {
try {
const rows = await query(
`SELECT column_label FROM table_type_columns
WHERE table_name = $1 AND column_name = $2 AND company_code = $3
LIMIT 1`,
[tblName, colName, companyCode]
);
const label = rows[0]?.column_label;
if (label) {
return `필수 입력값이 누락되었습니다: ${label}`;
}
} catch {
// 라벨 조회 실패 시 컬럼명으로 폴백
}
}
const detail = colName ? ` [${colName}]` : "";
return `필수 입력값이 누락되었습니다.${detail}`;
}
case "23505": {
// unique_violation
const constraint = error.constraint || "";
const tblName = error.table || "";
// constraint 이름에서 컬럼명 추출 시도 (예: item_mst_item_code_key → item_code)
let colName = "";
if (constraint && tblName) {
const prefix = `${tblName}_`;
const suffix = "_key";
if (constraint.startsWith(prefix) && constraint.endsWith(suffix)) {
colName = constraint.slice(prefix.length, -suffix.length);
}
}
if (colName && tblName && companyCode) {
try {
const rows = await query(
`SELECT column_label FROM table_type_columns
WHERE table_name = $1 AND column_name = $2 AND company_code = $3
LIMIT 1`,
[tblName, colName, companyCode]
);
const label = rows[0]?.column_label;
if (label) {
return `중복된 데이터가 존재합니다: ${label}`;
}
} catch {
// 폴백
}
}
const detail = colName ? ` [${colName}]` : "";
return `중복된 데이터가 존재합니다.${detail}`;
}
case "23503":
return "참조 무결성 제약 조건 위반입니다.";
default:
if (error.code.startsWith("23")) {
return "데이터 무결성 제약 조건 위반입니다.";
}
return error.message || "데이터 처리 중 오류가 발생했습니다.";
}
}