feat(sql-editor): 增加SQL错误中文语义提示

- 新增 SQL 执行错误语义化规则,覆盖语法、对象、字段、约束和连接类错误

- 执行失败和刷新失败展示中文语义、处理建议与原始错误

- 补充工具函数与 QueryEditor 回归测试,确保英文报错可读化
This commit is contained in:
Syngnat
2026-06-04 10:48:17 +08:00
parent a9d515f160
commit 9acb1c69f7
4 changed files with 258 additions and 6 deletions

View File

@@ -0,0 +1,46 @@
import { describe, expect, it } from 'vitest';
import { formatSqlExecutionError } from './sqlErrorSemantics';
describe('formatSqlExecutionError', () => {
it('adds Chinese semantic explanation for SQL syntax errors and keeps raw text', () => {
const formatted = formatSqlExecutionError('pq: syntax error at or near "from"');
expect(formatted).toContain('中文语义SQL 语法错误');
expect(formatted).toContain('处理建议:');
expect(formatted).toContain('原始错误pq: syntax error at or near "from"');
});
it('recognizes missing table errors', () => {
const formatted = formatSqlExecutionError('ERROR: relation "orders" does not exist');
expect(formatted).toContain('中文语义:表或对象不存在');
expect(formatted).toContain('原始错误ERROR: relation "orders" does not exist');
});
it('recognizes duplicate key errors with statement prefix', () => {
const formatted = formatSqlExecutionError('Duplicate entry "1" for key "PRIMARY"', {
prefix: '第 2 条语句执行失败:',
});
expect(formatted.startsWith('第 2 条语句执行失败:\n中文语义唯一约束或主键冲突')).toBe(true);
expect(formatted).toContain('原始错误Duplicate entry "1" for key "PRIMARY"');
});
it('falls back to a generic database execution error', () => {
const formatted = formatSqlExecutionError('driver returned unexpected status 123');
expect(formatted).toContain('中文语义:数据库执行错误');
expect(formatted).toContain('原始错误driver returned unexpected status 123');
});
it('does not format an already formatted message again', () => {
const raw = [
'中文语义SQL 语法错误。通常是关键字、逗号、括号、引号、语句顺序或当前数据库方言不匹配。',
'处理建议:检查报错位置附近的 SQL 片段,并确认当前连接的数据源类型与 SQL 方言一致。',
'原始错误pq: syntax error at or near "from"',
].join('\n');
expect(formatSqlExecutionError(raw)).toBe(raw);
});
});