From ecb972c71cbd39018321719b674ec8357d13cd76 Mon Sep 17 00:00:00 2001 From: Jason Wasem <46989741+Soein@users.noreply.github.com> Date: Thu, 18 Dec 2025 00:42:12 +0800 Subject: [PATCH 1/2] fix(search): add null check for canvas elements in fulltext search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加对 Canvas 笔记 elements 字段的空值检查,防止当 elements 为 null 或非数组时搜索功能报错。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../search/expressions/note_content_fulltext.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/server/src/services/search/expressions/note_content_fulltext.ts b/apps/server/src/services/search/expressions/note_content_fulltext.ts index 8a513d99b..21fd135c9 100644 --- a/apps/server/src/services/search/expressions/note_content_fulltext.ts +++ b/apps/server/src/services/search/expressions/note_content_fulltext.ts @@ -317,11 +317,16 @@ class NoteContentFulltextExp extends Expression { let canvasContent = JSON.parse(content); const elements: Element[] = canvasContent.elements; - const texts = elements - .filter((element: Element) => element.type === "text" && element.text) // Filter for 'text' type elements with a 'text' property - .map((element: Element) => element.text!); // Use `!` to assert `text` is defined after filtering - content = normalize(texts.toString()); + if (elements && Array.isArray(elements)) { + const texts = elements + .filter((element: Element) => element.type === "text" && element.text) // Filter for 'text' type elements with a 'text' property + .map((element: Element) => element.text!); // Use `!` to assert `text` is defined after filtering + + content = normalize(texts.toString()); + } else { + content = ""; + } } return content.trim(); From ee6f988c35ba29aca211b8f01baf88b78cbf80cd Mon Sep 17 00:00:00 2001 From: Jason Wasem <46989741+Soein@users.noreply.github.com> Date: Thu, 18 Dec 2025 10:01:13 +0800 Subject: [PATCH 2/2] refactor(search): simplify null check and use join for text concatenation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根据代码审查建议优化代码: - 移除多余的 `elements &&` 检查,因为 Array.isArray() 本身可处理 null/undefined - 使用 `join(" ")` 替代 `toString()` 以确保文本元素用空格分隔,更适合全文搜索 - 移除显式类型声明,让 TypeScript 自动推断 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../services/search/expressions/note_content_fulltext.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/server/src/services/search/expressions/note_content_fulltext.ts b/apps/server/src/services/search/expressions/note_content_fulltext.ts index 21fd135c9..89ba1bc98 100644 --- a/apps/server/src/services/search/expressions/note_content_fulltext.ts +++ b/apps/server/src/services/search/expressions/note_content_fulltext.ts @@ -315,15 +315,15 @@ class NoteContentFulltextExp extends Expression { [key: string]: any; // Other properties that may exist } - let canvasContent = JSON.parse(content); - const elements: Element[] = canvasContent.elements; + const canvasContent = JSON.parse(content); + const elements = canvasContent.elements; - if (elements && Array.isArray(elements)) { + if (Array.isArray(elements)) { const texts = elements .filter((element: Element) => element.type === "text" && element.text) // Filter for 'text' type elements with a 'text' property .map((element: Element) => element.text!); // Use `!` to assert `text` is defined after filtering - content = normalize(texts.toString()); + content = normalize(texts.join(" ")); } else { content = ""; }