继续收敛润色偏好 IPC 错误
保留提醒偏好读取和保存详情并显示回退状态 补充偏好错误处理文档
This commit is contained in:
+52
-14
@@ -41,7 +41,10 @@ import {
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import RichTextInput from '../../components/RichTextInput';
|
||||
import { captureClientError } from '../../services/errorReporting';
|
||||
import {
|
||||
captureClientError,
|
||||
visibleClientErrorMessage,
|
||||
} from '../../services/errorReporting';
|
||||
import type { UserContentPart } from '../../view/project-development/chat/generated/UserContentPart';
|
||||
import {
|
||||
chatPromptDraftKey,
|
||||
@@ -655,6 +658,9 @@ function ResourceReferenceEditor({
|
||||
// 聊天特有的「发送前提醒」:提醒偏好、本轮已确认草稿指纹与表单拦截。
|
||||
const [reminderOpen, setReminderOpen] = useState(false);
|
||||
const [reminderPolishing, setReminderPolishing] = useState(false);
|
||||
const [reminderPreferenceError, setReminderPreferenceError] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
// 偏好正式数据在 Rust:初始值只是「未关闭」的占位,挂载后由快照与事件补齐。
|
||||
const [reminderDisabled, setReminderDisabled] = useState(false);
|
||||
const acknowledgedDraftKeyRef = useRef<string | null>(null);
|
||||
@@ -681,6 +687,7 @@ function ResourceReferenceEditor({
|
||||
let unsubscribe: (() => void) | null = null;
|
||||
void subscribeChatPromptPolishReminderDisabled((disabled) => {
|
||||
if (disposed) return;
|
||||
setReminderPreferenceError(null);
|
||||
reminderPreferenceGenerationRef.current += 1;
|
||||
setReminderDisabled(disabled);
|
||||
})
|
||||
@@ -688,18 +695,41 @@ function ResourceReferenceEditor({
|
||||
if (disposed) release();
|
||||
else unsubscribe = release;
|
||||
})
|
||||
.catch(() => undefined);
|
||||
.catch((error) => {
|
||||
if (!disposed) {
|
||||
setReminderPreferenceError(
|
||||
`润色提醒偏好读取失败:${visibleClientErrorMessage(error)}`,
|
||||
);
|
||||
void captureClientError(error, {
|
||||
source: 'chat-prompt-polish',
|
||||
action: 'read-reminder-disabled',
|
||||
});
|
||||
}
|
||||
});
|
||||
// 快照读取与订阅并发,但只有「读取期间没有任何更新」时才允许写回。
|
||||
const generationAtRead = reminderPreferenceGenerationRef.current;
|
||||
void readChatPromptPolishReminderDisabled().then((disabled) => {
|
||||
if (
|
||||
disposed ||
|
||||
reminderPreferenceGenerationRef.current !== generationAtRead
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setReminderDisabled(disabled);
|
||||
});
|
||||
void readChatPromptPolishReminderDisabled()
|
||||
.then((disabled) => {
|
||||
if (
|
||||
disposed ||
|
||||
reminderPreferenceGenerationRef.current !== generationAtRead
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setReminderPreferenceError(null);
|
||||
setReminderDisabled(disabled);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (!disposed) {
|
||||
setReminderPreferenceError(
|
||||
`润色提醒偏好读取失败:${visibleClientErrorMessage(error)}`,
|
||||
);
|
||||
void captureClientError(error, {
|
||||
source: 'chat-prompt-polish',
|
||||
action: 'read-reminder-disabled',
|
||||
});
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
disposed = true;
|
||||
unsubscribe?.();
|
||||
@@ -805,9 +835,15 @@ function ResourceReferenceEditor({
|
||||
reminderPreferenceGenerationRef.current += 1;
|
||||
setReminderDisabled(disabled);
|
||||
void writeChatPromptPolishReminderDisabled(disabled)
|
||||
.then((persisted) => setReminderDisabled(persisted))
|
||||
.then((persisted) => {
|
||||
setReminderPreferenceError(null);
|
||||
setReminderDisabled(persisted);
|
||||
})
|
||||
.catch((error) => {
|
||||
setReminderDisabled(!disabled);
|
||||
setReminderPreferenceError(
|
||||
`润色提醒偏好保存失败:${visibleClientErrorMessage(error)}`,
|
||||
);
|
||||
captureClientError(error, {
|
||||
source: 'chat-prompt-polish',
|
||||
action: 'set-reminder-disabled',
|
||||
@@ -888,13 +924,15 @@ function ResourceReferenceEditor({
|
||||
{/* 「与原文相同 / 已截断」这类提示也要可见:只报失败会让「润色没变化」看起来像按钮坏了。 */}
|
||||
{showPolishAction &&
|
||||
!reminderOpen &&
|
||||
(polishing || polishError || polishNotice) ? (
|
||||
(polishing || polishError || polishNotice || reminderPreferenceError) ? (
|
||||
<span
|
||||
className="resource-reference-input-status"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
{polishing ? '润色中…' : (polishError ?? polishNotice)}
|
||||
{polishing
|
||||
? '润色中…'
|
||||
: (polishError ?? polishNotice ?? reminderPreferenceError)}
|
||||
</span>
|
||||
) : null}
|
||||
{providers.map((provider) =>
|
||||
|
||||
@@ -22,12 +22,8 @@ export const CHAT_PROMPT_POLISH_REMINDER_MIN_TEXT_LENGTH = 40;
|
||||
/** 读取 Rust 偏好投影;原生桥不可用时按未关闭处理。 */
|
||||
export async function readChatPromptPolishReminderDisabled(): Promise<boolean> {
|
||||
if (!resolveTauriInvoke()) return false;
|
||||
try {
|
||||
const snapshot = await readWorkspacePreferences();
|
||||
return snapshot.chatPromptPolishReminderDisabled;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const snapshot = await readWorkspacePreferences();
|
||||
return snapshot.chatPromptPolishReminderDisabled;
|
||||
}
|
||||
|
||||
/** 写入 Rust 偏好并返回落盘后的投影;原生桥不可用时只当成次生效。 */
|
||||
|
||||
@@ -141,6 +141,7 @@ DirectProject 已经解决过同一类问题([`【ADR】DirectProject命令接
|
||||
- 共享异步操作 hook(包括 Prompt Polish)捕获异常时,操作指引可以保留,但固定失败文案后必须附精确脱敏正文。
|
||||
- 资源画布历史任务账本读取属于用户可见的恢复路径:异常正文必须进入提示条;只有响应形状错误这类没有底层异常的情况才使用明确的契约提示。
|
||||
- 异步业务 facade 不得把底层异常折成“空结果”来逃避错误处理;只有真实的空回包、未配置或浏览器桥不可用等无正文事实允许返回空值,Tauri/网络/IPC 异常必须上抛到统一脱敏出口。
|
||||
- 可选偏好可以安全回退默认值,但回退不能隐藏错误:偏好读写 IPC 失败必须同时保留安全正文、记录诊断并在当前输入上下文给出提示。
|
||||
- Direct 活动回合事件桥注册失败即使仍有一次性快照,也必须标明事件更新通道已失联并展示安全正文,不能只显示旧快照而让用户误以为活动状态持续可靠。
|
||||
- 首页富文本剪贴板读取的“无内容”与“原生 IPC 失败”必须区分;后者展示安全正文,不能静默当作空剪贴板。
|
||||
- 账号邀请码复制与充值状态确认的失败提示也必须附安全正文;操作指引不能替换底层剪贴板、网络或支付查询原因。
|
||||
|
||||
@@ -62,6 +62,7 @@ DirectProject 回合失败在确认不是客户端内部不可归类故障时,
|
||||
- 共享 Prompt Polish hook 的注入请求/规范化/回填异常原来只显示固定失败提示;现保留精确脱敏后的异常正文,聊天输入和资源润色共用同一口径。
|
||||
- 资源画布历史生成任务账本读取失败原来统一显示“暂时无法恢复历史任务”;现在保留 Tauri/文件读取正文,非数组响应仍单独保留契约错误提示。
|
||||
- 发现默认 `requestChatPromptPolish` 还会把 Tauri 润色命令异常吞成 `null`,导致共享 hook 无法看到平台正文;现仅对空回包/桥不可用保留 `null`,原生异常继续上抛并统一脱敏。
|
||||
- 润色提醒偏好读取失败原来被当成“未关闭”默认值,写入失败只进错误上报池;现把读取/保存的 IPC 正文显示在输入区状态提示中,同时仍维持安全默认和回退行为。
|
||||
- Direct 活动回合事件桥注册失败原来只退回启动快照,面板没有说明后续更新已失联;现保留事件桥 IPC 正文并在标题栏/活动项目面板显示。
|
||||
- 首页富文本输入的原生剪贴板图片/文本读取失败原来直接按空剪贴板处理;现通过输入区错误提示保留脱敏后的剪贴板 IPC 正文。
|
||||
- 账号邀请码复制和微信充值状态确认仍有固定“复制失败/暂时没能确认到账”路径;现保留剪贴板/支付查询错误正文并继续给操作指引。
|
||||
|
||||
Reference in New Issue
Block a user