From 2ee2b2647eb3d392e8e464439d012f76c8dc880a Mon Sep 17 00:00:00 2001 From: Anton Evzhakov Date: Mon, 11 Sep 2023 13:22:49 +0300 Subject: [PATCH] fix(babel): actions reruns return unexpected undefined instead of throwing error when first run fails --- packages/babel/src/transform/actions/BaseAction.ts | 13 +++++++++++++ .../transform/actions/__tests__/BaseAction.test.ts | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/packages/babel/src/transform/actions/BaseAction.ts b/packages/babel/src/transform/actions/BaseAction.ts index 669b05c18..f62317ab7 100644 --- a/packages/babel/src/transform/actions/BaseAction.ts +++ b/packages/babel/src/transform/actions/BaseAction.ts @@ -42,6 +42,8 @@ export class BaseAction | AsyncScenarioForAction | null = null; + private activeScenarioError?: unknown; + private activeScenarioNextResults: AnyIteratorResult< 'async' | 'sync', TypeOfResult @@ -161,6 +163,7 @@ export class BaseAction return; } + this.activeScenarioError = errorInGenerator; throw errorInGenerator; } }; @@ -180,10 +183,20 @@ export class BaseAction return { next: (arg: YieldResult): IterationResult => { + if (this.activeScenarioError) { + // eslint-disable-next-line @typescript-eslint/no-throw-literal + throw this.activeScenarioError; + } + processNext(arg); return this.activeScenarioNextResults[nextIdx++] as IterationResult; }, throw: (e: unknown): IterationResult => { + if (this.activeScenarioError) { + // eslint-disable-next-line @typescript-eslint/no-throw-literal + throw this.activeScenarioError; + } + processError(e); return this.activeScenarioNextResults[nextIdx++] as IterationResult; }, diff --git a/packages/babel/src/transform/actions/__tests__/BaseAction.test.ts b/packages/babel/src/transform/actions/__tests__/BaseAction.test.ts index dcca06df0..c411d153c 100644 --- a/packages/babel/src/transform/actions/__tests__/BaseAction.test.ts +++ b/packages/babel/src/transform/actions/__tests__/BaseAction.test.ts @@ -169,5 +169,19 @@ describe('BaseAction', () => { expect(generator2.next()).toEqual({ done: true, value: null }); expect(onError).toHaveBeenCalledTimes(1); }); + + it("should rethrow error from every run if the first one didn't catch it", () => { + const error = new Error('foo'); + + const handler: Handler<'sync', ITransformAction> = function* handler() { + throw error; + }; + + const generator1 = action.run(handler); + const generator2 = action.run(handler); + + expect(() => generator1.next()).toThrow(error); + expect(() => generator2.next()).toThrow(error); + }); }); });