@lark-apaas/coding-template-nestjs-react-fullstack 0.1.47-alpha.20260930060132 → 0.1.47-alpha.20261005173706
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.
package/package.json
CHANGED
|
@@ -8,20 +8,12 @@ const SEP = ' ' + '─'.repeat(36);
|
|
|
8
8
|
|
|
9
9
|
function failAndExit(step, body) {
|
|
10
10
|
process.stderr.write('\n✗ pre-commit failed: ' + step + '\n');
|
|
11
|
-
process.stderr.write(' command: npm run lint\n');
|
|
12
11
|
process.stderr.write(SEP + '\n');
|
|
13
12
|
if (body && body.length > 0) {
|
|
14
|
-
process.stderr.write(body);
|
|
15
|
-
if (!body.endsWith('\n')) process.stderr.write('\n');
|
|
13
|
+
process.stderr.write(body.replace(/\s+$/, '') + '\n');
|
|
16
14
|
}
|
|
17
15
|
process.stderr.write(SEP + '\n');
|
|
18
|
-
process.stderr.write(
|
|
19
|
-
' 修复可编辑代码并重跑 npm run lint(原项目完整检查)。\n',
|
|
20
|
-
);
|
|
21
|
-
process.stderr.write(
|
|
22
|
-
' 命中平台受保护路径时停止反复编辑该文件或检查配置;记录路径、规则和检查原始输出,交有权限的平台维护者修复并复查。\n',
|
|
23
|
-
);
|
|
24
|
-
process.stderr.write(' 检查仍未通过;不得声称检查或提交成功。\n');
|
|
16
|
+
process.stderr.write(' bypass: git commit --no-verify\n');
|
|
25
17
|
process.exit(1);
|
|
26
18
|
}
|
|
27
19
|
|
|
@@ -33,7 +25,7 @@ function runLint() {
|
|
|
33
25
|
env: process.env,
|
|
34
26
|
});
|
|
35
27
|
if (res.error) {
|
|
36
|
-
failAndExit('lint', String(res.error.
|
|
28
|
+
failAndExit('lint', String(res.error.message || res.error));
|
|
37
29
|
}
|
|
38
30
|
if (res.status !== 0) {
|
|
39
31
|
const stdout = res.stdout ? res.stdout.toString() : '';
|
|
@@ -3,6 +3,7 @@ import type { Response } from 'express';
|
|
|
3
3
|
import { BusinessException } from '../interfaces/exception.interface';
|
|
4
4
|
import { HTTP_STATUS_TO_RESPONSE_CODE_MAP, ResponseCode } from '../constants/api_response_code';
|
|
5
5
|
import { ApiErrorResponse } from '../interfaces/api_response.interface';
|
|
6
|
+
import { hasPostgresSqlState } from '../utils/postgres-error';
|
|
6
7
|
|
|
7
8
|
// 全局异常过滤器,用于捕获所有未处理的异常
|
|
8
9
|
@Catch()
|
|
@@ -44,11 +45,7 @@ export class GlobalExceptionFilter implements ExceptionFilter {
|
|
|
44
45
|
timestamp: Date.now(),
|
|
45
46
|
},
|
|
46
47
|
};
|
|
47
|
-
} else if (
|
|
48
|
-
typeof exception === 'object' &&
|
|
49
|
-
exception !== null &&
|
|
50
|
-
(exception as { code?: unknown }).code === '22P02'
|
|
51
|
-
) {
|
|
48
|
+
} else if (hasPostgresSqlState(exception, '22P02')) {
|
|
52
49
|
// Postgres invalid_text_representation:路径/查询参数与列类型不匹配(最常见是非法 UUID)
|
|
53
50
|
// 与「合法 UUID 但记录不存在」走同一条 not-found 语义,避免 500 噪声
|
|
54
51
|
httpStatus = HttpStatus.NOT_FOUND;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const POSTGRES_SQLSTATE_PATTERN = /^[0-9A-Z]{5}$/u;
|
|
2
|
+
|
|
3
|
+
export const POSTGRES_ERROR_CAUSE_DEPTH_LIMIT = 8;
|
|
4
|
+
|
|
5
|
+
export function hasPostgresSqlState(
|
|
6
|
+
error: unknown,
|
|
7
|
+
expectedSqlState: string,
|
|
8
|
+
): boolean {
|
|
9
|
+
if (!POSTGRES_SQLSTATE_PATTERN.test(expectedSqlState)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const seen = new Set<object>();
|
|
14
|
+
let current: unknown = error;
|
|
15
|
+
|
|
16
|
+
for (
|
|
17
|
+
let depth = 0;
|
|
18
|
+
depth < POSTGRES_ERROR_CAUSE_DEPTH_LIMIT &&
|
|
19
|
+
current !== null &&
|
|
20
|
+
typeof current === 'object';
|
|
21
|
+
depth += 1
|
|
22
|
+
) {
|
|
23
|
+
if (seen.has(current)) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
seen.add(current);
|
|
27
|
+
|
|
28
|
+
const { code, cause } = current as { code?: unknown; cause?: unknown };
|
|
29
|
+
if (
|
|
30
|
+
typeof code === 'string' &&
|
|
31
|
+
POSTGRES_SQLSTATE_PATTERN.test(code) &&
|
|
32
|
+
code === expectedSqlState
|
|
33
|
+
) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
current = cause;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return false;
|
|
40
|
+
}
|