修复客户端更新诊断与错误展示

This commit is contained in:
2026-08-13 15:28:14 +08:00
parent a03043d048
commit f05b9d4cb5
5 changed files with 376 additions and 13 deletions

View File

@@ -17,6 +17,20 @@ function formatBytes(bytes: number): string {
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function formatUpdateError(error: string | null, fallback: string): string {
if (!error) return fallback;
const firstLine = error.replace(/\\r\\n|\\n|\r\n|\n/g, '\n').split('\n', 1)[0].trim();
const isTechnical =
/(?:^\w*Error\s*:|HttpError|Cannot find channel|node_modules|https?:\/\/|\bnet::ERR_[A-Z0-9_]+\b|\bE(?:ACCES|CONNREFUSED|CONNRESET|EXIST|HOSTUNREACH|ISDIR|NETUNREACH|NOENT|NOTDIR|PERM|PIPE|TIMEDOUT)\b|\b(?:ERR|UPDATER)_[A-Z0-9_]+\b|[A-Z]:\\|\\\\[^\\]|\bat\s+\S+\s*\()/i.test(
firstLine,
) || /^[{[]/.test(firstLine);
const isUserFacingProse = /\p{Script=Han}/u.test(firstLine);
if (!firstLine || firstLine.length > 180 || isTechnical || !isUserFacingProse) return fallback;
return firstLine;
}
export function UpdateSettings() {
const { t } = useTranslation('settings');
const {
@@ -75,7 +89,7 @@ export function UpdateSettings() {
case 'downloaded':
return t('updates.status.downloaded', { version: updateInfo?.version });
case 'error':
return error || t('updates.status.failed');
return formatUpdateError(error, t('updates.status.failed'));
case 'not-available':
return t('updates.status.latest');
default:
@@ -160,7 +174,9 @@ export function UpdateSettings() {
{/* Status */}
<div className="flex items-center justify-between py-3 border-t border-b">
<p className="text-sm text-muted-foreground">{renderStatusText()}</p>
<p className="min-w-0 flex-1 break-words pr-3 text-sm text-muted-foreground">
{renderStatusText()}
</p>
{renderAction()}
</div>
@@ -200,14 +216,6 @@ export function UpdateSettings() {
</div>
)}
{/* Error Details */}
{status === 'error' && error && (
<div className="rounded-lg bg-red-50 bg-red-500/10 p-4 text-red-600 text-red-700 text-sm">
<p className="font-medium mb-1">{t('updates.errorDetails')}</p>
<p>{error}</p>
</div>
)}
{/* Help Text */}
<p className="text-xs text-muted-foreground">
{t('updates.help')}