@cnbcool/cnb-api-generate 2.17.4 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,6 +5,7 @@ import { diagnoseBuild } from './build-diagnostics';
|
|
|
5
5
|
import { analyzeBuildTiming } from './build-timing';
|
|
6
6
|
import { formatParams } from './format-params';
|
|
7
7
|
import { formatOutput } from './format-output';
|
|
8
|
+
import { applyExitCode } from './exit-code';
|
|
8
9
|
import { buildToolParams } from './build-tool-params';
|
|
9
10
|
import { skillsList } from './skills-list';
|
|
10
11
|
// @ts-ignore
|
|
@@ -103,6 +104,8 @@ export async function executeAction(
|
|
|
103
104
|
data = await handleUpload(shortcut, opts.file, toolFunction, pathParams);
|
|
104
105
|
}
|
|
105
106
|
|
|
107
|
+
// 统一退出码策略:非 2xx 置非零退出码(见 lib/exit-code.ts)
|
|
108
|
+
applyExitCode(data);
|
|
106
109
|
console.log(formatOutput(data, isVerbose, !isVerbose, `${shortcut.module}/${shortcut.tool}`));
|
|
107
110
|
return;
|
|
108
111
|
}
|
|
@@ -148,5 +151,7 @@ export async function executeAction(
|
|
|
148
151
|
const toolKey = `${formattedParams.module}/${formattedParams.tool}`;
|
|
149
152
|
const isVerbose = !!formattedParams.verbose;
|
|
150
153
|
const isSummary = shortcut ? !isVerbose : false;
|
|
154
|
+
// 统一退出码策略:所有 API 响应都经此出口,非 2xx 置非零退出码
|
|
155
|
+
applyExitCode(data);
|
|
151
156
|
console.log(formatOutput(data, isVerbose, isSummary, toolKey));
|
|
152
157
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一退出码策略(见 cnb/skills/cnb-skill#458)
|
|
3
|
+
*
|
|
4
|
+
* 现状:`cnb` 的退出码只区分「命令名拼错」「未登录」两类失败,
|
|
5
|
+
* HTTP 4xx/5xx 一律 exit 0 —— 失败只体现在 stdout 的 `status:` 字段里。
|
|
6
|
+
* 对自动化(含 AI Agent)来说「退出码 0」就是成功信号,
|
|
7
|
+
* `cnb pulls submit-review` 在权限不足 / 编号写错时返回 4xx + exit 0,
|
|
8
|
+
* 看起来像已生效。
|
|
9
|
+
*
|
|
10
|
+
* 策略(本文件只做这一件事):HTTP 非 2xx 响应置非零退出码。
|
|
11
|
+
* 用 `process.exitCode` 而非 `process.exit()`:让已排队的 stdout 正常 flush,
|
|
12
|
+
* 输出内容不被截断,进程在事件循环结束后以非零码退出。
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** 退出码:与既有失败路径区分,便于脚本定位失败类型 */
|
|
16
|
+
export const EXIT_CODE_HTTP_ERROR = 1;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 从响应对象中解析 HTTP 状态码。
|
|
20
|
+
* 兼容 responseConverter 可能返回的裸 data(无 status 字段)。
|
|
21
|
+
*/
|
|
22
|
+
export function getResponseStatus(response: any): number | undefined {
|
|
23
|
+
if (response && typeof response === 'object' && typeof response.status === 'number') {
|
|
24
|
+
return response.status;
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 是否为 HTTP 成功响应(2xx) */
|
|
30
|
+
export function isHttpSuccess(status: number | undefined): boolean {
|
|
31
|
+
return typeof status === 'number' && status >= 200 && status < 300;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 按统一策略处理一次 API 调用结果:
|
|
36
|
+
* - 非 2xx 响应把退出码置为 1(不抛错,输出照旧)。
|
|
37
|
+
* - 拿不到 status(converter 返回的裸 data)时不误判失败。
|
|
38
|
+
*
|
|
39
|
+
* @param response 响应对象(含 status)
|
|
40
|
+
* @returns 该响应的 HTTP 状态码(无则 undefined)
|
|
41
|
+
*/
|
|
42
|
+
export function applyExitCode(response: any): number | undefined {
|
|
43
|
+
const status = getResponseStatus(response);
|
|
44
|
+
|
|
45
|
+
if (status !== undefined && !isHttpSuccess(status)) {
|
|
46
|
+
process.exitCode = EXIT_CODE_HTTP_ERROR;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return status;
|
|
50
|
+
}
|