diff --git a/.changeset/tidy-days-tease.md b/.changeset/tidy-days-tease.md new file mode 100644 index 00000000..d9b25a30 --- /dev/null +++ b/.changeset/tidy-days-tease.md @@ -0,0 +1,5 @@ +--- +"@defer/client": patch +--- + +Re-throw errors for local development diff --git a/src/index.ts b/src/index.ts index 2ac3d21e..c79bf948 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,20 +34,22 @@ export const deferEnabled = () => !!getEnv("DEFER_TOKEN"); async function execLocally( id: string, fn: any, - args: any + args: any, + shouldThrowErrors = false ): Promise { let state: client.ExecutionState = "succeed"; let originalResult: any; + let executionError: Error | undefined; try { originalResult = await fn(...args); } catch (error) { - const e = error as Error; + executionError = error as Error; state = "failed"; originalResult = { - name: e.name, - message: e.message, - cause: e.cause, - stack: e.stack, + name: executionError.name, + message: executionError.message, + cause: executionError.cause, + stack: executionError.stack, }; } @@ -62,6 +64,10 @@ async function execLocally( const response = { id, state, result }; __database.set(id, response); + if (executionError && shouldThrowErrors) { + throw executionError; + } + return response; } @@ -105,7 +111,7 @@ async function enqueue( const id = randomUUID(); __database.set(id, { id: id, state: "started" }); - execLocally(id, originalFunction, functionArguments); + execLocally(id, originalFunction, functionArguments, true); return { id }; } diff --git a/tests/awaitResult.spec.ts b/tests/awaitResult.spec.ts index e77e0d1e..4b36c095 100644 --- a/tests/awaitResult.spec.ts +++ b/tests/awaitResult.spec.ts @@ -1,4 +1,5 @@ import { awaitResult, defer } from "../src"; +import { DeferError } from "../src/errors"; import { makeHTTPClient } from "../src/httpClient"; import { jitter } from "../src/jitter"; @@ -61,4 +62,19 @@ describe("awaitResult(deferFn)", () => { }); }); }); + + describe("when Defer is inactive (`DEFER_TOKEN` is unset)", () => { + beforeAll(() => { + process.env["DEFER_TOKEN"] = ""; + }); + it("should rethrow any error as `DeferError`", async () => { + const myFunction = async (_str: string) => { + throw new Error("my function failed locally!"); + }; + const deferred = defer(myFunction); + const awaitable = awaitResult(deferred); + + await expect(awaitable("")).rejects.toThrow(DeferError); + }); + }); });