generated from tpl/obsidian-sample-plugin
Add error handling for create entry errors
This commit is contained in:
parent
09d1b08f7d
commit
e64e28cbe3
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
46
src/main.ts
46
src/main.ts
|
@ -140,34 +140,30 @@ 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,
|
authors: book.authors.map((a) => a.name).join(", "),
|
||||||
authors: book.authors.map((a) => a.name).join(", "),
|
})
|
||||||
})
|
.replace(/[/:*?<>|""]/g, "");
|
||||||
.replace(/[/:*?<>|""]/g, "");
|
|
||||||
|
|
||||||
const data: Record<string, unknown> = { book };
|
const data: Record<string, unknown> = { book };
|
||||||
|
|
||||||
if (this.settings.downloadCovers && book.coverImageUrl) {
|
if (this.settings.downloadCovers && book.coverImageUrl) {
|
||||||
const coverImageFile = await this.downloadCoverImage(
|
const coverImageFile = await this.downloadCoverImage(
|
||||||
book.coverImageUrl,
|
book.coverImageUrl,
|
||||||
fileName
|
fileName
|
||||||
);
|
|
||||||
data.coverImagePath = coverImageFile.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderedContent = await this.templater.renderTemplateFile(
|
|
||||||
this.settings.templateFile,
|
|
||||||
data
|
|
||||||
);
|
);
|
||||||
|
data.coverImagePath = coverImageFile.path;
|
||||||
const filePath = this.settings.tbrFolder + "/" + fileName + ".md";
|
|
||||||
const file = await this.app.vault.create(filePath, renderedContent);
|
|
||||||
await this.app.workspace.getLeaf().openFile(file);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to create book entry:", error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderedContent = await this.templater.renderTemplateFile(
|
||||||
|
this.settings.templateFile,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
|
const filePath = this.settings.tbrFolder + "/" + fileName + ".md";
|
||||||
|
const file = await this.app.vault.create(filePath, renderedContent);
|
||||||
|
await this.app.workspace.getLeaf().openFile(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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue