Files
Genarrative/apps/ai-game-creator-shell/tests/ErrorReportNotice.test.tsx
k88936 422c8931d6
Project CI / Repository checks (push) Successful in 2m45s
Project CI / Frontend tests (push) Successful in 3m22s
Project CI / Backend tests (push) Successful in 5m53s
Project CI / Native shell tests (push) Successful in 16m45s
Feat/AGC错误报告 (#240)
实现:
在rust内存里维护错误事件队列, webview调用tauri command传入, 后台任务agent工具等直接插入
把rust , webview console的日志统一写到AppData文件夹下的(滚动保存的)日志文件.
rust对传入的错误进行筛选,脱敏, 防抖,后通知前端提醒用户.
用户提醒是一个不阻塞的小UI, 展开后可以选择错误上报, 可以附加文字描述
上传时附带最近日志, 错误堆栈等信息

元数据存在数据库, 考虑到字符串信息很难查询, 所以在api server打包成zip存在OSS.
管理页面新增错误报告的查看页面

![shotmd-1788328504.jpg](/attachments/641b43c8-deed-47d8-8c78-36adb9a2548f)
![shotmd-1788328495.jpg](/attachments/33c6ada3-dd4d-44b6-9859-f18f944eb653)
![shotmd-1788328222.jpg](/attachments/59267df9-f624-4e47-bb9b-b69d77f595c4)
![shotmd-1788328230.jpg](/attachments/63ea6a86-9a51-412b-a98c-dce454bcc968)

---------

Co-authored-by: 段舒康 <kdletters@qq.com>
Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/240
Co-authored-by: 王德宇 <kvtodev@outlook.com>
Co-committed-by: 王德宇 <kvtodev@outlook.com>
2026-09-03 10:02:05 +08:00

68 lines
1.8 KiB
TypeScript

/** @vitest-environment jsdom */
import { cleanup, render, screen, waitFor } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
const mockState = vi.hoisted(() => ({
getPending: vi.fn(),
listeners: [] as Array<() => void>,
}));
vi.mock('../src/services/errorReporting', () => ({
getPendingClientErrorEvents: mockState.getPending,
subscribeClientErrorEvents: (listener: () => void) => {
mockState.listeners.push(listener);
return () => {
mockState.listeners = mockState.listeners.filter(
(item) => item !== listener,
);
};
},
}));
vi.mock('../src/components/error-report/ErrorReportDialog', () => ({
ErrorReportDialog: () => null,
}));
import { ErrorReportNotice } from '../src/components/error-report/ErrorReportNotice';
const event = {
eventId: 'rust-error-1',
fingerprint: 'fingerprint-1',
source: 'test',
message: '错过 emit 的错误',
occurredAt: '1',
count: 1,
};
describe('ErrorReportNotice', () => {
afterEach(() => {
cleanup();
mockState.getPending.mockReset();
mockState.listeners = [];
});
it('挂载时查询快照,即使错过唤醒事件也能显示通知', async () => {
mockState.getPending.mockResolvedValue([event]);
render(<ErrorReportNotice />);
expect(await screen.findByText('发现 1 个问题')).toBeTruthy();
expect(mockState.getPending).toHaveBeenCalledTimes(1);
});
it('收到唤醒后重新查询权威快照', async () => {
mockState.getPending
.mockResolvedValueOnce([])
.mockResolvedValueOnce([event]);
render(<ErrorReportNotice />);
await waitFor(() => expect(mockState.getPending).toHaveBeenCalledTimes(1));
mockState.listeners[0]?.();
expect(await screen.findByText('发现 1 个问题')).toBeTruthy();
expect(mockState.getPending).toHaveBeenCalledTimes(2);
});
});