AutoRpa/rpa_oracle/errors.py

76 lines
2.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Oracle 异常映射:ORA 码、约束名、固定对外文案。
from __future__ import annotations
import re
_ORA_CODE_RE = re.compile(r"ORA-(\d+)", re.I)
_CONSTRAINT_RE = re.compile(
r"unique constraint \((?:[\w$#]+\.)?([\w$#]+)\)",
re.I,
)
SALES_OMS_ID_CONSTRAINT = "UK_RPA_SGMD_OMS_ID"
CONTRACT_FID_CONSTRAINTS = frozenset({"PK_RPA_PCD"})
# 数据库连不上、未配置或 thick client 初始化失败。
#
# 对外消息固定为「数据库不可用」,不带 DSN、库路径或 ORA 原文。
class RepoUnavailable(Exception):
# 记下对外文案。默认「数据库不可用」,不要把 ORA 原文传进来。
def __init__(self, message: str = "数据库不可用"):
self.message = message
super().__init__(message)
# 取出异常上的 Oracle 错误号,没有则返回 None。
def ora_code(exc: BaseException) -> int | None:
if exc.args:
info = exc.args[0]
code = getattr(info, "code", None)
if code is not None:
return int(code)
code = getattr(exc, "code", None)
if code is not None:
return int(code)
match = _ORA_CODE_RE.search(str(exc))
if match:
return int(match.group(1))
return None
# 从 ORA-00001 报文里取出约束名(不含 schema),没有则返回 None。
def ora_constraint(exc: BaseException) -> str | None:
chunks: list[str] = [str(exc)]
if exc.args:
info = exc.args[0]
message = getattr(info, "message", None)
if message:
chunks.append(str(message))
for text in chunks:
match = _CONSTRAINT_RE.search(text)
if match:
return match.group(1)
return None
# 是否为表 1 oms_id 唯一约束冲突(接口 1 DUPLICATE)。
#
# 只有约束名是 uk_rpa_sgmd_oms_id 才算。其它唯一约束即使是 ORA-00001 也返回 False。
def is_sales_oms_id_duplicate(exc: BaseException) -> bool:
if ora_code(exc) != 1:
return False
name = ora_constraint(exc)
return bool(name) and name.upper() == SALES_OMS_ID_CONSTRAINT
# 是否为表 3 fid 主键冲突(接口 3 DUPLICATE)。
#
# 目前对应 pk_rpa_pcd。未知唯一约束返回 False。
def is_contract_fid_duplicate(exc: BaseException) -> bool:
if ora_code(exc) != 1:
return False
name = ora_constraint(exc)
return bool(name) and name.upper() in CONTRACT_FID_CONSTRAINTS