From aec34d139a1c8753869e01b34bb4d5a2d88bb35a Mon Sep 17 00:00:00 2001 From: wren Date: Wed, 25 Mar 2026 17:29:21 +0800 Subject: [PATCH] fix(frontend): comprehensive defensive guards in ReviewSettings Multiple locations in ReviewSettings.tsx call .includes() or .filter() on variables that could theoretically be non-arrays: 1. availableFields.filter/.includes - added safeAvailableFields guard 2. newFields.map field.includes('_') - added typeof===string guard + filter 3. (prior fix) cfgAvailableFields includes/every in renderRuleConfig 4. (prior fix) selectedFields includes in renderFieldTags These prevent TypeError crashes when config objects contain unexpected types (e.g. {} instead of []) from stale API data. Co-Authored-By: Claude Opus 4.6 --- app/components/rules/new/ReviewSettings.tsx | 25 ++++++++++++--------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/app/components/rules/new/ReviewSettings.tsx b/app/components/rules/new/ReviewSettings.tsx index fba23c7..08ab865 100644 --- a/app/components/rules/new/ReviewSettings.tsx +++ b/app/components/rules/new/ReviewSettings.tsx @@ -387,11 +387,12 @@ export function ReviewSettings({ // 去重 const uniqueFields = [...new Set(processedFields)]; - // 检查是否有字段被删除 - const deletedFields = availableFields.filter(field => !uniqueFields.includes(field)); - + // 检查是否有字段被删除(防御性:确保availableFields是数组) + const safeAvailableFields: string[] = Array.isArray(availableFields) ? availableFields : []; + const deletedFields = safeAvailableFields.filter(field => !uniqueFields.includes(field)); + // 处理新增的字段 - const newFields = uniqueFields.filter((field: string) => !availableFields.includes(field)); + const newFields = uniqueFields.filter((field: string) => !safeAvailableFields.includes(field)); if (newFields.length > 0 || deletedFields.length > 0) { // console.log('Updating fields in checkAndUpdateFields - deleted:', deletedFields, 'new:', newFields); @@ -538,13 +539,15 @@ export function ReviewSettings({ const updatedConfig = { ...rule.config }; // 对所有规则类型都更新availableFields字段 - // 处理字段,只保留字段名,去掉类型后缀 - const processedFields = newFields.map(field => { - if (field.includes('_')) { - return field.split('_')[0]; // 只保留类型前面的字段名 - } - return field; - }); + // 处理字段,只保留字段名,去掉类型后缀(防御性:确保field是字符串) + const processedFields = newFields + .filter(field => typeof field === 'string') + .map(field => { + if (field.includes('_')) { + return field.split('_')[0]; + } + return field; + }); // 去重 const uniqueFields = [...new Set(processedFields)];