From bfca45751075f2bb4ba48911149ef50a1d174787 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 6 Nov 2023 11:21:43 +0900 Subject: [PATCH] enhance(frontend): improve aiscript plugin error handling --- packages/frontend/src/boot/main-boot.ts | 2 +- packages/frontend/src/components/MkNote.vue | 14 ++++++++++---- .../frontend/src/components/MkNoteDetailed.vue | 14 ++++++++++---- packages/frontend/src/components/MkPostForm.vue | 6 +++++- packages/frontend/src/plugin.ts | 12 +++++++++--- 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts index b11d0db04..887740f4a 100644 --- a/packages/frontend/src/boot/main-boot.ts +++ b/packages/frontend/src/boot/main-boot.ts @@ -58,7 +58,7 @@ export async function mainBoot() { }); for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) { - import('../plugin').then(async ({ install }) => { + import('@/plugin.js').then(async ({ install }) => { // Workaround for https://bugs.webkit.org/show_bug.cgi?id=242740 await new Promise(r => setTimeout(r, 0)); install(plugin); diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 0ae3423a2..cd02f96bc 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -202,11 +202,17 @@ let note = $ref(deepClone(props.note)); // plugin if (noteViewInterruptors.length > 0) { onMounted(async () => { - let result:Misskey.entities.Note | null = deepClone(note); + let result: Misskey.entities.Note | null = deepClone(note); for (const interruptor of noteViewInterruptors) { - result = await interruptor.handler(result); - - if (result === null) return isDeleted.value = true; + try { + result = await interruptor.handler(result); + if (result === null) { + isDeleted.value = true; + return; + } + } catch (err) { + console.error(err); + } } note = result; }); diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 1d8049934..74dcf08da 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -239,11 +239,17 @@ let note = $ref(deepClone(props.note)); // plugin if (noteViewInterruptors.length > 0) { onMounted(async () => { - let result:Misskey.entities.Note | null = deepClone(note); + let result: Misskey.entities.Note | null = deepClone(note); for (const interruptor of noteViewInterruptors) { - result = await interruptor.handler(result); - - if (result === null) return isDeleted.value = true; + try { + result = await interruptor.handler(result); + if (result === null) { + isDeleted.value = true; + return; + } + } catch (err) { + console.error(err); + } } note = result; }); diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index c0fd1c14d..512fb892e 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -750,7 +750,11 @@ async function post(ev?: MouseEvent) { // plugin if (notePostInterruptors.length > 0) { for (const interruptor of notePostInterruptors) { - postData = await interruptor.handler(deepClone(postData)); + try { + postData = await interruptor.handler(deepClone(postData)); + } catch (err) { + console.error(err); + } } } diff --git a/packages/frontend/src/plugin.ts b/packages/frontend/src/plugin.ts index 3bc91f6ac..e24f646a3 100644 --- a/packages/frontend/src/plugin.ts +++ b/packages/frontend/src/plugin.ts @@ -11,10 +11,9 @@ import { Plugin, noteActions, notePostInterruptors, noteViewInterruptors, postFo const parser = new Parser(); const pluginContexts = new Map(); -export function install(plugin: Plugin): void { +export async function install(plugin: Plugin): Promise { // 後方互換性のため if (plugin.src == null) return; - console.info('Plugin installed:', plugin.name, 'v' + plugin.version); const aiscript = new Interpreter(createPluginEnv({ plugin: plugin, @@ -42,7 +41,14 @@ export function install(plugin: Plugin): void { initPlugin({ plugin, aiscript }); - aiscript.exec(parser.parse(plugin.src)); + try { + await aiscript.exec(parser.parse(plugin.src)); + } catch (err) { + console.error('Plugin install failed:', plugin.name, 'v' + plugin.version); + return; + } + + console.info('Plugin installed:', plugin.name, 'v' + plugin.version); } function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Record {