From 291a991dbce980947268bfd645d524c90db6b009 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 18 May 2026 11:04:43 +0000 Subject: [PATCH] fix(models): show real errors when client config import scan fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit importClientConfigs interpolated humanizeError() into a template string; humanizeError returns an object, so users only saw "[object Object]". Pass the structured result to toast() with importScanFailed as context. Add node tests documenting the humanizeError coercion pitfall. Co-authored-by: 晴天 <1186258278@users.noreply.github.com> --- src/pages/models.js | 2 +- tests/humanize-error.test.js | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/humanize-error.test.js diff --git a/src/pages/models.js b/src/pages/models.js index f96b17f..724fa9c 100644 --- a/src/pages/models.js +++ b/src/pages/models.js @@ -1308,7 +1308,7 @@ async function importClientConfigs(page, state) { const result = await api.scanModelClientConfigs() candidates = Array.isArray(result?.candidates) ? result.candidates : [] } catch (e) { - toast(`${t('models.importScanFailed')}: ${humanizeError(e)}`, 'error') + toast(humanizeError(e, t('models.importScanFailed')), 'error') return } finally { if (btn) { btn.disabled = false; btn.textContent = oldText || t('models.importClientConfigs') } diff --git a/tests/humanize-error.test.js b/tests/humanize-error.test.js new file mode 100644 index 0000000..2bc7cc4 --- /dev/null +++ b/tests/humanize-error.test.js @@ -0,0 +1,23 @@ +/** + * humanize-error.js contract: return value is a structured object for toast(), + * not for string interpolation (coerces to "[object Object]"). + * + * 运行:node --test tests/humanize-error.test.js + */ +import test from 'node:test' +import assert from 'node:assert/strict' + +import { humanizeError, humanizeErrorText } from '../src/lib/humanize-error.js' + +test('humanizeError must not be coerced with String() or template literals', () => { + const h = humanizeError(new Error('ECONNREFUSED 127.0.0.1:443'), 'Import scan failed') + assert.equal(typeof h, 'object') + assert.equal(String(h), '[object Object]') + assert.ok(h.message) +}) + +test('humanizeErrorText is safe for plain-string contexts', () => { + const line = humanizeErrorText(new Error('ENOENT no such file'), 'Import scan failed') + assert.match(line, /Import scan failed/) + assert.doesNotMatch(line, /\[object Object\]/) +})