From 32a1c5adc0f1883a6ee331c790c751adc879079e Mon Sep 17 00:00:00 2001 From: xintaofei Date: Fri, 3 Apr 2026 23:38:25 +0800 Subject: [PATCH] fix: improve error message when exporting long conversations as image Co-Authored-By: Claude Opus 4.6 (1M context) --- .../conversation-detail-panel.tsx | 7 +++++- src/i18n/messages/ar.json | 1 + src/i18n/messages/de.json | 1 + src/i18n/messages/en.json | 1 + src/i18n/messages/es.json | 1 + src/i18n/messages/fr.json | 1 + src/i18n/messages/ja.json | 1 + src/i18n/messages/ko.json | 1 + src/i18n/messages/pt.json | 1 + src/i18n/messages/zh-CN.json | 1 + src/i18n/messages/zh-TW.json | 1 + src/lib/export-conversation.ts | 22 ++++++++++++++----- 12 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/components/conversations/conversation-detail-panel.tsx b/src/components/conversations/conversation-detail-panel.tsx index abe9374..abb2a7e 100644 --- a/src/components/conversations/conversation-detail-panel.tsx +++ b/src/components/conversations/conversation-detail-panel.tsx @@ -71,6 +71,7 @@ import { exportAsHtml, exportAsImage, exportAsMarkdown, + ExportTooLongError, type ExportLabels, } from "@/lib/export-conversation" @@ -1275,7 +1276,11 @@ export function ConversationDetailPanel() { toast.success(t("exportSuccess")) } catch (err) { updateTask(taskId, { status: "failed" }) - toast.error(t("exportFailed")) + if (err instanceof ExportTooLongError) { + toast.error(t("exportImageTooLong")) + } else { + toast.error(t("exportFailed")) + } console.error("[ConversationDetailPanel] export image:", err) } }, [getExportData, t, addTask, updateTask]) diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index 8a3435b..ae85281 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "تم تصدير المحادثة", "exportFailed": "فشل التصدير", + "exportImageTooLong": "المحادثة طويلة جداً ولا يمكن تصديرها كصورة", "exportLabels": { "untitledConversation": "محادثة بدون عنوان", "agent": "الوكيل", diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 080378f..9a3862a 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "Konversation exportiert", "exportFailed": "Export fehlgeschlagen", + "exportImageTooLong": "Konversation ist zu lang für den Bildexport", "exportLabels": { "untitledConversation": "Unbenannte Konversation", "agent": "Agent", diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index c4e81a5..41db5f2 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "Conversation exported", "exportFailed": "Export failed", + "exportImageTooLong": "Conversation is too long to export as image", "exportLabels": { "untitledConversation": "Untitled Conversation", "agent": "Agent", diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json index 175126a..dbf82ea 100644 --- a/src/i18n/messages/es.json +++ b/src/i18n/messages/es.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "Conversación exportada", "exportFailed": "Error al exportar", + "exportImageTooLong": "La conversación es demasiado larga para exportar como imagen", "exportLabels": { "untitledConversation": "Conversación sin título", "agent": "Agente", diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index d6b4384..cbfef2a 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "Conversation exportée", "exportFailed": "Échec de l'exportation", + "exportImageTooLong": "La conversation est trop longue pour être exportée en image", "exportLabels": { "untitledConversation": "Conversation sans titre", "agent": "Agent", diff --git a/src/i18n/messages/ja.json b/src/i18n/messages/ja.json index 8d21176..cf72b0d 100644 --- a/src/i18n/messages/ja.json +++ b/src/i18n/messages/ja.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "会話をエクスポートしました", "exportFailed": "エクスポートに失敗しました", + "exportImageTooLong": "会話が長すぎるため、画像としてエクスポートできません", "exportLabels": { "untitledConversation": "無題の会話", "agent": "エージェント", diff --git a/src/i18n/messages/ko.json b/src/i18n/messages/ko.json index e07128f..d854f8a 100644 --- a/src/i18n/messages/ko.json +++ b/src/i18n/messages/ko.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "대화를 내보냈습니다", "exportFailed": "내보내기 실패", + "exportImageTooLong": "대화가 너무 길어 이미지로 내보낼 수 없습니다", "exportLabels": { "untitledConversation": "제목 없는 대화", "agent": "에이전트", diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index 526ea82..0c8798d 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "Conversa exportada", "exportFailed": "Falha ao exportar", + "exportImageTooLong": "A conversa é muito longa para exportar como imagem", "exportLabels": { "untitledConversation": "Conversa sem título", "agent": "Agente", diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json index 2ccb976..fcb1c27 100644 --- a/src/i18n/messages/zh-CN.json +++ b/src/i18n/messages/zh-CN.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "会话已导出", "exportFailed": "导出失败", + "exportImageTooLong": "会话内容过长,不支持导出为图片", "exportLabels": { "untitledConversation": "未命名会话", "agent": "代理", diff --git a/src/i18n/messages/zh-TW.json b/src/i18n/messages/zh-TW.json index 091f66d..60b1439 100644 --- a/src/i18n/messages/zh-TW.json +++ b/src/i18n/messages/zh-TW.json @@ -743,6 +743,7 @@ "exportHtml": "HTML", "exportSuccess": "對話已匯出", "exportFailed": "匯出失敗", + "exportImageTooLong": "對話內容過長,不支援匯出為圖片", "exportLabels": { "untitledConversation": "未命名對話", "agent": "代理", diff --git a/src/lib/export-conversation.ts b/src/lib/export-conversation.ts index 80ab51f..bf7908d 100644 --- a/src/lib/export-conversation.ts +++ b/src/lib/export-conversation.ts @@ -445,6 +445,13 @@ export function exportAsHtml(data: ExportConversationData): void { // Safari caps at 16384, Chrome at ~32767. Use a safe limit. const MAX_IMAGE_HEIGHT = 16000 +export class ExportTooLongError extends Error { + constructor() { + super("Content too long for image export") + this.name = "ExportTooLongError" + } +} + export async function exportAsImage( data: ExportConversationData ): Promise { @@ -477,11 +484,16 @@ export async function exportAsImage( }) const target = iframeDoc.querySelector(".container") ?? body - const dataUrl = await toPng(target as HTMLElement, { - width: 800, - pixelRatio: 2, - backgroundColor: "#f9fafb", - }) + let dataUrl: string + try { + dataUrl = await toPng(target as HTMLElement, { + width: 800, + pixelRatio: 2, + backgroundColor: "#f9fafb", + }) + } catch { + throw new ExportTooLongError() + } const res = await fetch(dataUrl) const blob = await res.blob() const url = URL.createObjectURL(blob)