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 (<anonymous>)
    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 (<cmd/ctrl>+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 (<anonymous>)
    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)
```
This commit is contained in:
Bao
2024-11-05 11:40:58 -06:00
committed by GitHub
parent 01a9e976e6
commit 1c98d8b2d7
2 changed files with 16 additions and 5 deletions

View File

@@ -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)

View File

@@ -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')