7.2 KiB
7.2 KiB
错误处理流程
sap-cli 命令失败时的标准处理流程。严格按顺序执行。
通用流程
命令失败
↓
1. 诊断根因(使用方式错误 or 代码/环境问题?)
↓
2. 使用方式错误 → 修正参数后重试
↓
3. sap-cli 限制 → 报告失败,不绕过
↓
4. SAP 系统限制 → 穷尽自动化方案
↓
5. 确认无法自动化 → 请求用户 SAP GUI 操作
步骤 1:诊断根因
检查以下项目:
| 检查项 | 方法 |
|---|---|
| 命令参数是否正确 | 对照 python main.py --help 和 SKILL.md 验证参数 |
| 文件是否存在、内容是否为空 | cat 或 ls 检查 |
| 传输请求号是否正确 | python main.py transport info --corr_nr DEVK901XXX |
| 网络连接是否正常 | python main.py config show 验证配置 |
| 对象是否存在于 SAP | python main.py info --name XXX --type class |
步骤 2:使用方式错误
修正后重试。常见修正:
- 缺少
--corr_nr→ 加上传输请求号 - 对象名大小写错误 → sap-cli 会自动处理,但路径要注意
- 文件路径错误 → 检查相对/绝对路径
- 对象类型不匹配 → 用
python main.py --help确认支持的类型
步骤 3:sap-cli 限制
如果确认不是使用方式问题,如实报告错误信息,不要尝试绕过 sap-cli:
❌ 错误做法:写 Python requests 脚本绕过
❌ 错误做法:用 curl 直接调 ADT 端点
❌ 错误做法:导入 ADTClient 调内部方法
✅ 正确做法:报告失败,说明原因
步骤 4:穷尽自动化方案(SAP 系统限制时)
遇到 SAP 系统限制时,按以下顺序穷尽自动化方案:
方案 A:调整 sap-cli 参数重试
- 尝试不同的
--corr_nr - 尝试
--dry-run预览后执行 - 检查是否有残留锁(
show-table查看 SM12 相关信息)
方案 B:ABAP 报表 workaround
通过 run-program 执行辅助报表:
# 清除残留锁
python main.py sync --type report --name ZSAPILOT_CLEAR_LOCKS --path <file> --corr_nr DEVK901XXX
python main.py run-program --name ZSAPILOT_CLEAR_LOCKS
方案 C:delete + recreate
如果对象需要完全重写:
python main.py delete --name ZMY_CLASS --type class
python main.py sync --name ZMY_CLASS --type class --path <file> --corr_nr DEVK901XXX
注意:delete 可能因传输请求绑定而失败(HTTP 423),此时需要用户在 SE09 操作。
方案 D:activate 单独重试
python main.py activate --name ZMY_CLASS --type class --corr_nr DEVK901XXX
NW 7.40 的 double-activate 已内置在 sap-cli 中。如果 activate 仍然失败,不要再尝试其他激活策略,直接报告给用户。
步骤 5:请求用户 SAP GUI 操作
只在确认所有自动化方案穷尽后才请求用户操作。
必须一次性给出完整操作清单
当需要用户在 SAP GUI 操作时,绝不能渐进式发现问题:
- ❌ 错误:先让用户加字段 A,测试后发现缺字段 B,又让用户加字段 B
- ✅ 正确:先做全面对比分析(
show-tablevs 代码中的字段引用),一次性给出完整变更清单
系统表操作的 4 步授权流程
如果需要操作系统表(唯一的例外情况):
- 解释原因 — 为什么需要操作系统表
- 列出具体操作 — 表名 + 操作类型(如
DELETE FROM SEOCLASS WHERE ...) - 说明风险和替代方案 — 可能的副作用、有没有不操作系统表的替代方案
- 等待用户确认 — 得到明确授权后才执行
常见失败场景速查
| 错误 | 常见原因 | 处理方式 |
|---|---|---|
| HTTP 406 (info 查 DDIC) | NW 7.40 不支持 DDIC 专属媒体类型;application/xml 同样 406,只有 */* 可用 |
工具已内置 */* 回退,无需手工处理 |
| HTTP 406 (Lock DDIC) | NW 7.40 不支持 DDIC 对象 ADT Lock | 报告用户,SE09 处理 |
| HTTP 403 (Locked) | 残留 enqueue lock | 先尝试 run-program 清锁报表,不行才 SM12 |
| HTTP 400 (SaveFailure) | 类 DEFINITION 与 SAP 不一致 | 检查本地 vs SAP 的 DEFINITION 差异 |
| HTTP 423 (Transport lock) | 对象绑定在传输请求中 | 报告用户,SE09 处理 |
| 激活失败仍 inactive | NW 7.40 ADT 限制 | sap-cli 已内置 double-activate,仍失败则报告用户去 SE09 |
WITH EMPTY KEY 运行 dump |
NW 7.40 不支持 | 修改为 WITH NON-UNIQUE KEY 或 WITH DEFAULT KEY |
HTTP 400 (Data Preview) A Boolean expression was expected in <字段>= |
运算符两侧缺空格:WHERE f='x' 解析失败(= 被黏在值上);WHERE f = 'x'(有空格)实测 200 |
运算符两侧留空格,或一律用 IN (...) / LIKE '...' |
HTTP 400 (Data Preview) elements in the SELECT LIST list must be separated using commas |
选择列必须逗号分隔(SELECT a b 报错) |
写成 SELECT a, b FROM t |
HTTP 400 (Data Preview) 未知的列名称 "<COL>" until runtime |
SELECT/WHERE 用了不存在的列名(如 DD02T 没有 LANGUAGE/MASTERLANG,语言列是 DDLANGUAGE) |
先确认 DDIC 列名再查;报错已携带 SAP 原文 |
info 的「传输请求」恒为 (无法获取) |
(已修复)旧版 _query_transport_request 用无空格 = 查 E071 必 400 且异常被吞 |
已改 IN (...) 并区分「无」与「无法获取」 |
ADT Data Preview SQL 方言(NW 7.40 实测,2026-09-11 二次修订)
用于补 ZMM_BIP 系列等元数据时,本系统 /sap/bc/adt/datapreview/freestyle 的 SQL 解析器要求:
| 能力 | 实测结果 |
|---|---|
SELECT f1, f2 FROM t(逗号分隔) |
✅ 200 |
WHERE f = 'a'(运算符两侧有空格) |
✅ 200(2026-09-11 复测纠正:早前「不支持 =」的结论是探针写法无空格所致) |
WHERE f='a'(无空格) |
❌ 400 A Boolean expression was expected |
WHERE f IN ('a','b') |
✅ 200 |
WHERE f LIKE 'ZMM%' |
✅ 200 |
SELECT f1 f2(无逗号) |
❌ 400 要求逗号分隔 |
SELECT <不存在的列> |
❌ 400 未知的列名称 "X" until runtime(SAP 原文会指明列名) |
| 无 WHERE 全表 | ✅ 200(但行数受行数参数与授权限制) |
可用的元数据来源(本机实测):
| 对象类型 | 描述表(键, 语言, 文本) | 开发包来源 |
|---|---|---|
| 结构 / 表 | DD02T(TABNAME/DDLANGUAGE/DDTEXT) |
TADIR(OBJECT='TABL') |
| 表类型 | DD40T(TYPENAME/DDLANGUAGE/DDTEXT) |
TADIR(OBJECT='TTYP') |
| 数据元素 | DD04T(ROLLNAME/DDLANGUAGE/DDTEXT) |
TADIR(OBJECT='DTEL') |
| 域 | DD01T(DOMNAME/DDLANGUAGE/DDTEXT) |
TADIR(OBJECT='DOMA') |
| 类 | ADT 已直接提供 | TADIR(OBJECT='CLAS') |
- 描述文本的语言不统一:同一批 ZMM_BIP 结构里有的只有
DDLANGUAGE='1',有的只有'E';补全时必须按「登录语言 →E→1→ 首行」回退,不能硬取一种。 - ZMM_BIP 系列 9 个 DDIC 对象在
TADIR里查不到任何行(结构与表类型均无注册)→ 无法从系统取得开发包,也意味着未登记对象目录(传输/对象清单角度需注意)。