Add error handling for create entry errors

This commit is contained in:
Evan Fiordeliso 2025-07-01 11:06:45 -04:00
parent 09d1b08f7d
commit e64e28cbe3
5 changed files with 44 additions and 44 deletions

View File

@ -8,7 +8,7 @@ const GOODREADS_URL_PATTERN = /https:\/\/www.goodreads.com\/book\/show\/(\d+)/;
export class CreateBookFromGoodreadsUrlCommand extends Command { export class CreateBookFromGoodreadsUrlCommand extends Command {
constructor( constructor(
private readonly goodreads: Goodreads, private readonly goodreads: Goodreads,
private readonly cb: (book: Book) => void | PromiseLike<void> private readonly createEntry: (book: Book) => void | PromiseLike<void>
) { ) {
super( super(
"create-book-from-goodreads-url", "create-book-from-goodreads-url",
@ -40,7 +40,14 @@ export class CreateBookFromGoodreadsUrlCommand extends Command {
return; return;
} }
await this.cb(book); try {
await this.createEntry(book);
} catch (error) {
console.error("Failed to create book:", error);
new Notice("Failed to create book. Check console for details.");
return;
}
new Notice("Book created from Goodreads URL."); new Notice("Book created from Goodreads URL.");
} }
} }

View File

@ -8,7 +8,7 @@ export class SearchGoodreadsCommand extends Command {
constructor( constructor(
private readonly app: App, private readonly app: App,
private readonly goodreads: Goodreads, private readonly goodreads: Goodreads,
private readonly cb: (book: Book) => void private readonly createEntry: (book: Book) => void | PromiseLike<void>
) { ) {
super("search-goodreads", "Search Goodreads"); super("search-goodreads", "Search Goodreads");
} }
@ -50,6 +50,14 @@ export class SearchGoodreadsCommand extends Command {
return; return;
} }
this.cb(book); try {
await this.createEntry(book);
} catch (error) {
console.error("Failed to create book:", error);
new Notice("Failed to create book. Check console for details.");
return;
}
new Notice("Book created from search result.");
} }
} }

View File

@ -140,7 +140,6 @@ export default class BookTrackerPlugin extends Plugin {
} }
async createEntry(book: Book): Promise<void> { async createEntry(book: Book): Promise<void> {
try {
const fileName = this.templater const fileName = this.templater
.renderTemplate(this.settings.fileNameFormat, { .renderTemplate(this.settings.fileNameFormat, {
title: book.title, title: book.title,
@ -166,8 +165,5 @@ export default class BookTrackerPlugin extends Plugin {
const filePath = this.settings.tbrFolder + "/" + fileName + ".md"; const filePath = this.settings.tbrFolder + "/" + fileName + ".md";
const file = await this.app.vault.create(filePath, renderedContent); const file = await this.app.vault.create(filePath, renderedContent);
await this.app.workspace.getLeaf().openFile(file); await this.app.workspace.getLeaf().openFile(file);
} catch (error) {
console.error("Failed to create book entry:", error);
}
} }
} }

View File

@ -8,14 +8,12 @@
<script lang="ts"> <script lang="ts">
import { clickOutside } from "@ui/directives"; import { clickOutside } from "@ui/directives";
import { App, Scope } from "obsidian";
import { onMount, type Snippet } from "svelte"; import { onMount, type Snippet } from "svelte";
import { createPopperActions } from "svelte-popperjs"; import { createPopperActions } from "svelte-popperjs";
type T = $$Generic; type T = $$Generic;
type Props = { type Props = {
app: App;
id: string; id: string;
items: Item<T>[]; items: Item<T>[];
value?: T; value?: T;
@ -26,7 +24,6 @@
}; };
let { let {
app,
id, id,
items, items,
value = $bindable(), value = $bindable(),
@ -41,8 +38,8 @@
let selectedIndex = $state(0); let selectedIndex = $state(0);
let listEl: HTMLUListElement | null = $state(null); let listEl: HTMLUListElement | null = $state(null);
onMount(async () => { $effect(() => {
await onChange?.(query); onChange?.(query);
}); });
$effect.root(() => { $effect.root(() => {
@ -101,7 +98,6 @@
const item = items[index]; const item = items[index];
if (!item) return; if (!item) return;
const { text: newQuery, value: newValue } = item; const { text: newQuery, value: newValue } = item;
selectedIndex = index; selectedIndex = index;
expanded = false; expanded = false;
query = newQuery; query = newQuery;
@ -110,11 +106,6 @@
await onSelected?.(newValue); await onSelected?.(newValue);
} }
async function handleInput() {
expanded = true;
await onChange?.(query);
}
async function clearSearch() { async function clearSearch() {
query = ""; query = "";
value = undefined; value = undefined;
@ -159,7 +150,6 @@
class:is-loading={loading} class:is-loading={loading}
aria-busy={loading} aria-busy={loading}
use:clickOutside={() => (expanded = false)} use:clickOutside={() => (expanded = false)}
onfocusout={() => (expanded = false)}
> >
<div class="search-input-container"> <div class="search-input-container">
<input <input
@ -171,7 +161,7 @@
spellcheck="false" spellcheck="false"
role="combobox" role="combobox"
bind:value={query} bind:value={query}
oninput={handleInput} oninput={() => (expanded = true)}
onfocusin={() => (expanded = true)} onfocusin={() => (expanded = true)}
aria-controls={`${id}-list`} aria-controls={`${id}-list`}
aria-autocomplete="list" aria-autocomplete="list"

View File

@ -8,7 +8,6 @@
import type BookTrackerPlugin from "@src/main"; import type BookTrackerPlugin from "@src/main";
import { createSettingsStore } from "./store"; import { createSettingsStore } from "./store";
import { onMount } from "svelte"; import { onMount } from "svelte";
import FieldSuggest from "@ui/components/suggesters/FieldSuggest.svelte";
type Props = { type Props = {
plugin: BookTrackerPlugin; plugin: BookTrackerPlugin;
@ -45,7 +44,7 @@
id="read-folder" id="read-folder"
name="Read Books Folder" name="Read Books Folder"
description="Select the folder to use for Read entries." description="Select the folder to use for Read entries."
bind:value={$settings.tbrFolder} bind:value={$settings.readBooksFolder}
/> />
<ToggleItem <ToggleItem
id="organize-read-books" id="organize-read-books"