From 1c98d8b2d7f84eaffb0a1f1871f87d5532e84713 Mon Sep 17 00:00:00 2001 From: Bao <6306455+baodrate@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:40:58 -0600 Subject: [PATCH] Fix uncaught exceptions (#414) * Fix handling of folders on create trigger When creating a directory in the vault, omnisearch attempts to index the directory as a document `on('create', (file) => any, ...)` is triggered for both files and directories, so any triggers on `create` should handle the case where `file` is a `TFolder`.[^1] [^1]: https://docs.obsidian.md/Reference/TypeScript+API/Vault/on('create') For example, after running `mkdir foobar` in the vault directory, the following exception is thrown: ```stacktrace documents-repository.ts:53 Omnisearch: Error while adding "foobar" to live cache Error: Not a TFile: "foobar" at DocumentsRepository.getAndMapIndexedDocument (documents-repository.ts:85:41) at DocumentsRepository.addDocument (documents-repository.ts:43:30) at DocumentsRepository.getDocument (documents-repository.ts:69:16) at eval (search-engine.ts:82:63) at Array.map () at SearchEngine.addFromPaths (search-engine.ts:81:15) at eval (main.ts:114:26) at e.tryTrigger (app.js:1:723011) at e.trigger (app.js:1:722944) at t.trigger (app.js:1:741049) ``` * Fix handling of empty canvas files Canvas files can be empty. e.g. when the "Create new canvas" command is called: - immediately after the command: - a new *empty* .canvas file will be created - triggering the `create` event and causing a "Unexpected end of JSON input" error - when saving the file (+s or "Save current file" command): - `{}` will be written to the file - triggering a file `modify` event and causing a "canvas.nodes is not iterable" exception Examples of the exceptions: ```stacktrace documents-repository.ts:53 Omnisearch: Error while adding "Untitled.canvas" to live cache SyntaxError: Unexpected end of JSON input at JSON.parse () at DocumentsRepository.getAndMapIndexedDocument (documents-repository.ts:100:27) at async DocumentsRepository.addDocument (documents-repository.ts:43:19) at async DocumentsRepository.getDocument (documents-repository.ts:69:5) at async eval (search-engine.ts:82:25) at async Promise.all (index 0) at async SearchEngine.addFromPaths (search-engine.ts:80:7) ``` ```stacktrace documents-repository.ts:53 Omnisearch: Error while adding "Untitled.canvas" to live cache TypeError: canvas.nodes is not iterable at DocumentsRepository.getAndMapIndexedDocument (documents-repository.ts:103:33) at async DocumentsRepository.addDocument (documents-repository.ts:43:19) at async NotesIndexer.refreshIndex (notes-indexer.ts:29:7) ``` --- src/main.ts | 14 ++++++++++++-- src/repositories/documents-repository.ts | 7 ++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main.ts b/src/main.ts index d51eff5..dbaeb9e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,11 @@ -import { App, Notice, Platform, Plugin, type PluginManifest } from 'obsidian' +import { + App, + Notice, + Platform, + Plugin, + type PluginManifest, + TFile, +} from 'obsidian' import { OmnisearchInFileModal, OmnisearchVaultModal, @@ -109,7 +116,10 @@ export default class OmnisearchPlugin extends Plugin { // Listeners to keep the search index up-to-date this.registerEvent( this.app.vault.on('create', file => { - if (this.notesIndexer.isFileIndexable(file.path)) { + if ( + file instanceof TFile && + this.notesIndexer.isFileIndexable(file.path) + ) { logDebug('Indexing new file', file.path) searchEngine.addFromPaths([file.path]) this.embedsRepository.refreshEmbedsForNote(file.path) diff --git a/src/repositories/documents-repository.ts b/src/repositories/documents-repository.ts index ba702de..d064697 100644 --- a/src/repositories/documents-repository.ts +++ b/src/repositories/documents-repository.ts @@ -97,17 +97,18 @@ export class DocumentsRepository { // ** Canvas ** // Extract the text fields from the json else if (isFileCanvas(path)) { - const canvas = JSON.parse(await app.vault.cachedRead(file)) as CanvasData + const fileContents = await app.vault.cachedRead(file) + const canvas: CanvasData = fileContents ? JSON.parse(fileContents) : {} let texts: string[] = [] // Concatenate text from the canvas fields - for (const node of canvas.nodes) { + for (const node of canvas.nodes ?? []) { if (node.type === 'text') { texts.push(node.text) } else if (node.type === 'file') { texts.push(node.file) } } - for (const edge of canvas.edges.filter(e => !!e.label)) { + for (const edge of (canvas.edges ?? []).filter(e => !!e.label)) { texts.push(edge.label!) } content = texts.join('\r\n')