diff --git a/src/Schema.ts b/src/Schema.ts index c33009a1e..93081578d 100644 --- a/src/Schema.ts +++ b/src/Schema.ts @@ -3372,8 +3372,8 @@ const optionFrom = (value: Schema): Schema, OptionFrom }) ) -const optionDecode = (o: OptionFrom): Option.Option => - o._tag === "None" ? Option.none() : Option.some(o.value) +const optionDecode = (input: OptionFrom): Option.Option => + input._tag === "None" ? Option.none() : Option.some(input.value) const optionArbitrary = (value: Arbitrary): Arbitrary> => { const placeholder = lazy(() => any).pipe(annotations({ @@ -3476,8 +3476,8 @@ const eitherFrom = ( }) ) -const eitherDecode = (e: EitherFrom): Either.Either => - e._tag === "Left" ? Either.left(e.left) : Either.right(e.right) +const eitherDecode = (input: EitherFrom): Either.Either => + input._tag === "Left" ? Either.left(input.left) : Either.right(input.right) const eitherArbitrary = ( left: Arbitrary, @@ -4618,36 +4618,6 @@ const causeFrom = (error: Schema): Schema, CauseFrom }) ) -const causeTraverse = ( - cause: Cause.Cause, - parseError: (e: E, options: ParseOptions) => ParseResult.ParseResult, - options: ParseOptions -): ParseResult.ParseResult> => { - if (cause._tag === "Fail") { - return ParseResult.map(parseError(cause.error, options), Cause.fail) - } else if (cause._tag === "Parallel") { - return ParseResult.flatMap( - causeTraverse(cause.left, parseError, options), - (left) => - ParseResult.map( - causeTraverse(cause.right, parseError, options), - (right) => Cause.parallel(left, right) - ) - ) - } else if (cause._tag === "Sequential") { - return ParseResult.flatMap( - causeTraverse(cause.left, parseError, options), - (left) => - ParseResult.map( - causeTraverse(cause.right, parseError, options), - (right) => Cause.sequential(left, right) - ) - ) - } - - return ParseResult.succeed(cause) -} - const causeArbitrary = (error: Arbitrary): Arbitrary> => { const placeholder = lazy(() => any).pipe(annotations({ [hooks.ArbitraryHookId]: () => error @@ -4682,17 +4652,17 @@ const causePretty = (error: Pretty): Pretty> => (cause) => */ export const causeFromSelf = ( error: Schema -): Schema, Cause.Cause> => - declare( +): Schema, Cause.Cause> => { + return declare( [error], causeFrom(error), (isDecoding, error) => { - const parseError = isDecoding ? Parser.parse(error) : Parser.encode(error) + const parse = isDecoding ? Parser.parse(causeFrom(error)) : Parser.encode(causeFrom(error)) return (u, options, ast) => { - if (!Cause.isCause(u)) { - return ParseResult.fail(ParseResult.type(ast, u)) + if (Cause.isCause(u)) { + return ParseResult.map(parse(causeEncode(u), options), causeDecode) } - return causeTraverse(u, parseError, options) + return ParseResult.fail(ParseResult.type(ast, u)) } }, { @@ -4702,6 +4672,7 @@ export const causeFromSelf = ( [hooks.EquivalenceHookId]: () => Equal.equals } ) +} function causeDecode(cause: CauseFrom): Cause.Cause { switch (cause._tag) { @@ -4725,7 +4696,7 @@ function causeEncode(cause: Cause.Cause): CauseFrom { case "Empty": return { _tag: "Empty" } case "Die": - return { _tag: "Die", defect: Cause.pretty(cause) } + return { _tag: "Die", defect: cause.defect } case "Interrupt": return { _tag: "Interrupt", fiberId: cause.fiberId } case "Fail": diff --git a/test/Cause/cause.test.ts b/test/Cause/cause.test.ts index 1d5c1a220..31358aed8 100644 --- a/test/Cause/cause.test.ts +++ b/test/Cause/cause.test.ts @@ -64,6 +64,22 @@ describe("Cause/cause", () => { }, Cause.interrupt(FiberId.composite(FiberId.runtime(1, 1000), FiberId.none)) ) + + await Util.expectParseFailure( + schema, + null, + `Expected , actual null` + ) + await Util.expectParseFailure( + schema, + {}, + `/_tag is missing` + ) + await Util.expectParseFailure( + schema, + { _tag: "Parallel", left: { _tag: "Fail" }, right: { _tag: "Interrupt" } }, + `union member: /left union member: /error is missing` + ) }) it("encoding", async () => { @@ -82,7 +98,7 @@ describe("Cause/cause", () => { }) await Util.expectEncodeSuccess(schema, Cause.die("fail"), { _tag: "Die", - defect: "Error: fail" + defect: "fail" }) await Util.expectEncodeSuccess( schema, @@ -105,7 +121,7 @@ describe("Cause/cause", () => { const failWithStack = S.encodeSync(schema)(Cause.die(new Error("fail"))) assert(failWithStack._tag === "Die") - assert.include(failWithStack.defect, "Error: fail") - assert.include(failWithStack.defect, "cause.test.ts") + assert.include(String(failWithStack.defect), "Error: fail") + assert.include(String((failWithStack.defect as any).stack), "cause.test.ts") }) }) diff --git a/test/Cause/causeFromSelf.test.ts b/test/Cause/causeFromSelf.test.ts index 66309fe07..e428a1f01 100644 --- a/test/Cause/causeFromSelf.test.ts +++ b/test/Cause/causeFromSelf.test.ts @@ -16,6 +16,16 @@ describe("Cause/causeFromSelf", () => { await Util.expectParseSuccess(schema, Cause.fail("1"), Cause.fail(1)) await Util.expectParseFailure(schema, null, `Expected Cause, actual null`) + await Util.expectParseFailure( + schema, + Cause.fail("a"), + `union member: /error Expected string <-> number, actual "a"` + ) + await Util.expectParseFailure( + schema, + Cause.parallel(Cause.die("error"), Cause.fail("a")), + `union member: /right union member: /error Expected string <-> number, actual "a"` + ) }) it("encoding", async () => {