Skip to content

Commit ff88f80

Browse files
authoredFeb 14, 2024··
Fix Cause.pretty when toString is invalid (#2143)
1 parent 11be07b commit ff88f80

File tree

4 files changed

+50
-19
lines changed

4 files changed

+50
-19
lines changed
 

‎.changeset/honest-cameras-nail.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"effect": patch
3+
---
4+
5+
Fix Cause.pretty when toString is invalid
6+
7+
```ts
8+
import { Cause } from "effect";
9+
10+
console.log(Cause.pretty(Cause.fail([{ toString: "" }])));
11+
```
12+
13+
The code above used to throw now it prints:
14+
15+
```bash
16+
Error: [{"toString":""}]
17+
```

‎packages/effect/src/internal/cause.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -1040,12 +1040,17 @@ export const prettyErrorMessage = (u: unknown): string => {
10401040
return `Error: ${u}`
10411041
}
10421042
// 2)
1043-
if (
1044-
hasProperty(u, "toString") &&
1045-
isFunction(u["toString"]) &&
1046-
u["toString"] !== Object.prototype.toString
1047-
) {
1048-
return u["toString"]()
1043+
try {
1044+
if (
1045+
hasProperty(u, "toString") &&
1046+
isFunction(u["toString"]) &&
1047+
u["toString"] !== Object.prototype.toString &&
1048+
u["toString"] !== Array.prototype.toString
1049+
) {
1050+
return u["toString"]()
1051+
}
1052+
} catch {
1053+
// something's off, rollback to json
10491054
}
10501055
// 3)
10511056
return `Error: ${JSON.stringify(u)}`

‎packages/effect/test/Cause.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,10 @@ describe("Cause", () => {
354354
}
355355
})
356356
})
357+
358+
describe("Pretty", () => {
359+
it("doesn't blow up on array errors", () => {
360+
assert.strictEqual(Cause.pretty(Cause.fail([{ toString: "" }])), `Error: [{"toString":""}]`)
361+
})
362+
})
357363
})

‎packages/schema/test/util.ts

+16-13
Original file line numberDiff line numberDiff line change
@@ -79,26 +79,29 @@ const effectifyAST = (ast: AST.AST): AST.AST => {
7979
export const effectify = <A, I>(schema: S.Schema<A, I, never>): S.Schema<A, I, never> =>
8080
S.make(effectifyAST(schema.ast))
8181

82-
export const roundtrip = <A, I>(schema: S.Schema<A, I, never>) => {
82+
export const roundtrip = <A, I>(schema: S.Schema<A, I, never>, params?: Parameters<typeof fc.assert>[1]) => {
8383
if (!doRoundtrip) {
8484
return
8585
}
8686
const arb = A.make(schema)
8787
const is = S.is(schema)
8888
const encode = S.encode(schema)
8989
const decode = S.decode(schema)
90-
fc.assert(fc.property(arb(fc), (a) => {
91-
const roundtrip = encode(a).pipe(
92-
Effect.mapError(() => "encoding" as const),
93-
Effect.flatMap((i) => decode(i).pipe(Effect.mapError(() => "decoding" as const))),
94-
Effect.either,
95-
Effect.runSync
96-
)
97-
if (Either.isLeft(roundtrip)) {
98-
return roundtrip.left === "encoding"
99-
}
100-
return is(roundtrip.right)
101-
}))
90+
fc.assert(
91+
fc.property(arb(fc), (a) => {
92+
const roundtrip = encode(a).pipe(
93+
Effect.mapError(() => "encoding" as const),
94+
Effect.flatMap((i) => decode(i).pipe(Effect.mapError(() => "decoding" as const))),
95+
Effect.either,
96+
Effect.runSync
97+
)
98+
if (Either.isLeft(roundtrip)) {
99+
return roundtrip.left === "encoding"
100+
}
101+
return is(roundtrip.right)
102+
}),
103+
params
104+
)
102105
if (doEffectify) {
103106
const effectSchema = effectify(schema)
104107
const encode = S.encode(effectSchema)

0 commit comments

Comments
 (0)
Please sign in to comment.