diff --git a/.changeset/nasty-queens-pull.md b/.changeset/nasty-queens-pull.md new file mode 100644 index 0000000000..59d3076901 --- /dev/null +++ b/.changeset/nasty-queens-pull.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +ensure all Data.Error arguments are preserved in .toJSON diff --git a/packages/effect/src/Data.ts b/packages/effect/src/Data.ts index ac4d27bd41..6b02cc2df7 100644 --- a/packages/effect/src/Data.ts +++ b/packages/effect/src/Data.ts @@ -530,13 +530,18 @@ export const Error: new = {}>( args: Types.Equals extends true ? void : { readonly [P in keyof A]: A[P] } ) => Cause.YieldableError & Readonly = (function() { + const plainArgsSymbol = Symbol.for("effect/Data/Error/plainArgs") return class Base extends core.YieldableError { constructor(args: any) { super(args?.message, args?.cause ? { cause: args.cause } : undefined) if (args) { Object.assign(this, args) + Object.defineProperty(this, plainArgsSymbol, { value: args, enumerable: false }) } } + toJSON() { + return { ...(this as any)[plainArgsSymbol], ...this } + } } as any })() diff --git a/packages/effect/test/Data.test.ts b/packages/effect/test/Data.test.ts index 2420c6c1de..7fab66478e 100644 --- a/packages/effect/test/Data.test.ts +++ b/packages/effect/test/Data.test.ts @@ -279,5 +279,24 @@ describe("Data", () => { expect(e.message).toStrictEqual("Oh no!") expect(e.a).toStrictEqual(1) }) + + it("toJSON includes all args", () => { + class MyError extends Data.Error<{ message: string; a: number; cause: string }> {} + const e = new MyError({ message: "Oh no!", a: 1, cause: "Boom" }) + assert.deepStrictEqual(e.toJSON(), { message: "Oh no!", a: 1, cause: "Boom" }) + }) + }) + + describe("TaggedError", () => { + it("toJSON includes all args", () => { + class MyError extends Data.TaggedError("MyError")<{ message: string; a: number; cause: string }> {} + const e = new MyError({ message: "Oh no!", a: 1, cause: "Boom" }) + assert.deepStrictEqual(e.toJSON(), { + _tag: "MyError", + message: "Oh no!", + a: 1, + cause: "Boom" + }) + }) }) })