diff --git a/denops/tataku/load.ts b/denops/tataku/load.ts index e2fe1dc..8c658ba 100644 --- a/denops/tataku/load.ts +++ b/denops/tataku/load.ts @@ -13,7 +13,7 @@ type Query = { name: string; }; -type Factory = (denops: Denops, options: unknown) => T; +type Factory = (denops: Denops, options: unknown) => T | Promise; function search( denops: Denops, @@ -91,7 +91,7 @@ export function loadProcessor( .andThen((path) => { return ResultAsync.fromPromise( import(path.href).then((e) => e.default), - (cause) => new Error(`Failed to processor-${name}`, { cause }), + (cause) => new Error(`Failed to load processor-${name}`, { cause }), ); }) .andThen((factory: unknown) => { @@ -110,7 +110,7 @@ export function loadEmitter( .andThen((path) => { return ResultAsync.fromPromise( import(path.href).then((e) => e.default), - (cause) => new Error(`Failed to emitter-${name}`, { cause }), + (cause) => new Error(`Failed to load emitter-${name}`, { cause }), ); }) .andThen((factory: unknown) => { diff --git a/denops/tataku/tataku.ts b/denops/tataku/tataku.ts index 1b00074..9c06a55 100644 --- a/denops/tataku/tataku.ts +++ b/denops/tataku/tataku.ts @@ -8,6 +8,7 @@ import { validate, } from "./types.ts"; import { loadCollector, loadEmitter, loadProcessor } from "./load.ts"; +import { convertError } from "./utils.ts"; type Streams = { collector: Collector; @@ -42,19 +43,29 @@ export function prepareStreams( ResultAsync.combine([ loadCollector(denops, recipe.collector.name) .andThen((factory) => - okAsync(factory(denops, recipe.collector.options ?? {})) + ResultAsync.fromPromise( + Promise.resolve(factory(denops, recipe.collector.options ?? {})), + convertError("Failed to load collector"), + ) ), ResultAsync.combine( recipe.processor.map((page) => loadProcessor(denops, page.name) .andThen((factory) => - okAsync(factory(denops, page.options ?? {})) + ResultAsync.fromPromise( + Promise.resolve(factory(denops, page.options ?? {})), + convertError("Failed to load processor"), + ) ) ), - ).andThen((streams) => okAsync(new CombinedProcessorStream(streams))), + ) + .andThen((streams) => okAsync(new CombinedProcessorStream(streams))), loadEmitter(denops, recipe.emitter.name) .andThen((factory) => - okAsync(factory(denops, recipe.emitter.options ?? {})) + ResultAsync.fromPromise( + Promise.resolve(factory(denops, recipe.emitter.options ?? {})), + convertError("Failed to load emitter"), + ) ), ]) ) diff --git a/denops/tataku/utils.ts b/denops/tataku/utils.ts index a0a1dee..8fbd91e 100644 --- a/denops/tataku/utils.ts +++ b/denops/tataku/utils.ts @@ -35,3 +35,19 @@ export async function handleError( ); } } + +/** + * Convert some value to Error + * + * @param cause Some error thing + * @param message The message of error if using cause is not Error + * @returns Converted error + */ +export function convertError(message = "Failed"): (e: unknown) => Error { + return (cause) => { + if (cause instanceof Error) { + return cause; + } + return new Error(message, { cause }); + }; +}