PayrollManagementSystem/backend/app/services/tplus/errors.py

36 lines
1.5 KiB
Python
Raw Normal View History

"""只按明确的源驱动错误分类,不把含凭据的驱动文本写入响应。"""
from sqlalchemy.exc import TimeoutError as PoolTimeoutError
TRANSIENT_CODES = frozenset({"SOURCE_CONNECTION_LOST", "SOURCE_TIMEOUT"})
MESSAGES = {
"SOURCE_CONNECTION_LOST": "源连接中断,请检查网络和只读连接",
"SOURCE_TIMEOUT": "源连接或查询超时",
"SOURCE_AUTH_ERROR": "源账号认证失败,请核对只读账号配置",
"SOURCE_SCHEMA_ERROR": "源表或字段不匹配,请核对版本与映射",
"SOURCE_CONFIG_ERROR": "源连接配置不完整或任务排队后发生变化",
"SOURCE_DRIVER_ERROR": "源数据库驱动不可用,请检查已验证的ODBC驱动",
"QUERY_FILE_MISSING": "缺少源查询文件,请核对部署包",
}
def classify_source_error(exc, fallback="READ_ERROR"):
if isinstance(exc, (TimeoutError, PoolTimeoutError)):
return "SOURCE_TIMEOUT"
if isinstance(exc, ModuleNotFoundError):
return "SOURCE_DRIVER_ERROR"
if isinstance(exc, FileNotFoundError):
return "QUERY_FILE_MISSING"
original = getattr(exc, "orig", exc)
args = getattr(original, "args", ())
state = str(args[0]).upper() if args else ""
if state in {"HYT00", "HYT01"}:
return "SOURCE_TIMEOUT"
if state in {"08S01", "08001", "08003", "08006"}:
return "SOURCE_CONNECTION_LOST"
if state == "28000":
return "SOURCE_AUTH_ERROR"
if state in {"42S02", "42S22", "07002"}:
return "SOURCE_SCHEMA_ERROR"
return fallback