From bde540b9ad10eb4b2f10ed91300247d5434e3383 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 13 Sep 2024 10:43:15 +1200 Subject: [PATCH] make Exit.failCause refails work --- packages/effect/src/internal/cause.ts | 27 +++++++++++++++++---------- packages/effect/src/internal/core.ts | 20 ++++++-------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/packages/effect/src/internal/cause.ts b/packages/effect/src/internal/cause.ts index 2054b163d9a..317fb97c17d 100644 --- a/packages/effect/src/internal/cause.ts +++ b/packages/effect/src/internal/cause.ts @@ -94,7 +94,7 @@ export const fail = (error: E): Cause.Cause => { const o = Object.create(proto) o._tag = OpCodes.OP_FAIL o.error = error - return o + return rehydrateAnnotations(o, error) } /** @internal */ @@ -102,7 +102,7 @@ export const die = (defect: unknown): Cause.Cause => { const o = Object.create(proto) o._tag = OpCodes.OP_DIE o.defect = defect - return o + return rehydrateAnnotations(o, defect) } /** @internal */ @@ -136,15 +136,19 @@ export const annotated = dual< (context: Context.Context) => (self: Cause.Cause) => Cause.Cause, (self: Cause.Cause, context: Context.Context) => Cause.Cause >(2, (self, context) => { + if (self._tag === OpCodes.OP_ANNOTATED && self.context === context) { + return self + } const o = Object.create(proto) o._tag = OpCodes.OP_ANNOTATED if (self._tag === OpCodes.OP_ANNOTATED) { o.context = Context.merge(context, self.context) - o.cause = propagateAnnotations(self.cause, o.context) + o.cause = self.cause } else { o.context = context - o.cause = propagateAnnotations(self, context) + o.cause = self } + propagateAnnotations(o.cause, o.context) return o }) @@ -1321,16 +1325,19 @@ function addOriginalAnnotations(obj: E, annotations: Context.Context): }) } -const propagateAnnotations = (self: Cause.Cause, context: Context.Context): Cause.Cause => { +const rehydrateAnnotations = (self: Cause.Cause, obj: unknown): Cause.Cause => { + const annotations = originalAnnotations(obj) + return annotations ? annotated(self, annotations) : self +} + +const propagateAnnotations = (self: Cause.Cause, context: Context.Context): void => { switch (self._tag) { case "Die": { - return die(addOriginalAnnotations(self.defect, context)) + ;(self as any).defect = addOriginalAnnotations(self.defect, context) + break } case "Fail": { - return fail(addOriginalAnnotations(self.error, context)) - } - default: { - return self + ;(self as any).error = addOriginalAnnotations(self.error, context) } } } diff --git a/packages/effect/src/internal/core.ts b/packages/effect/src/internal/core.ts index b874298966e..a4c07b2ea0a 100644 --- a/packages/effect/src/internal/core.ts +++ b/packages/effect/src/internal/core.ts @@ -662,21 +662,15 @@ export const checkInterruptible = ( f: (isInterruptible: boolean) => Effect.Effect ): Effect.Effect => withFiberRuntime((_, status) => f(_runtimeFlags.interruption(status.runtimeFlags))) -const capture = (cause: Cause.Cause, obj?: unknown): Effect.Effect => +const capture = (cause: Cause.Cause): Effect.Effect => withFiberRuntime((fiber) => { - const originalAnnotations = internalCause.originalAnnotations(obj) - if (originalAnnotations) { - cause = internalCause.annotated(cause, originalAnnotations) - } else { - const span = currentSpanFromFiber(fiber) - let context = Context.empty() - if (span._tag === "Some") { - context = Context.add(context, internalCause.FailureSpan, span.value) - } - cause = Context.isEmpty(context) ? cause : internalCause.annotated(cause, context) + const span = currentSpanFromFiber(fiber) + let context = Context.empty() + if (span._tag === "Some") { + context = Context.add(context, internalCause.FailureSpan, span.value) } const effect = new EffectPrimitiveFailure(OpCodes.OP_FAILURE) as any - effect.effect_instruction_i0 = cause + effect.effect_instruction_i0 = Context.isEmpty(context) ? cause : internalCause.annotated(cause, context) return effect }) @@ -714,9 +708,7 @@ export const failSync = (evaluate: LazyArg): Effect.Effect => fl export const failCause = (cause: Cause.Cause): Effect.Effect => { switch (cause._tag) { case "Fail": - return capture(cause, cause.error) case "Die": - return capture(cause, cause.defect) case "Interrupt": return capture(cause) default: {