Skip to content

Commit a03b6a2

Browse files
luchersoutim-smart
andauthored
fix(logger): use source maps for error stack traces in browser pretty logger (#6093)
Co-authored-by: Tim Smart <hello@timsmart.co>
1 parent 7d8fc1e commit a03b6a2

4 files changed

Lines changed: 52 additions & 48 deletions

File tree

.changeset/slow-hands-draw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": patch
3+
---
4+
5+
avoid class for PrettyError to preserve error.name

packages/effect/src/internal/cause.ts

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { pipeArguments } from "../Pipeable.js"
1414
import type { Predicate, Refinement } from "../Predicate.js"
1515
import { hasProperty, isFunction } from "../Predicate.js"
1616
import type { AnySpan, Span } from "../Tracer.js"
17-
import type { NoInfer } from "../Types.js"
17+
import type * as Types from "../Types.js"
1818
import { getBugErrorMessage } from "./errors.js"
1919
import * as OpCodes from "./opCodes/cause.js"
2020

@@ -879,59 +879,58 @@ export const pretty = <E>(cause: Cause.Cause<E>, options?: {
879879
if (options?.renderErrorCause !== true || e.cause === undefined) {
880880
return e.stack
881881
}
882-
return `${e.stack} {\n${renderErrorCause(e.cause as PrettyError, " ")}\n}`
882+
return `${e.stack} {\n${renderErrorCause(e.cause as Cause.PrettyError, " ")}\n}`
883883
}).join("\n")
884884
}
885885

886-
const renderErrorCause = (cause: PrettyError, prefix: string) => {
886+
const renderErrorCause = (cause: Cause.PrettyError, prefix: string) => {
887887
const lines = cause.stack!.split("\n")
888888
let stack = `${prefix}[cause]: ${lines[0]}`
889889
for (let i = 1, len = lines.length; i < len; i++) {
890890
stack += `\n${prefix}${lines[i]}`
891891
}
892892
if (cause.cause) {
893-
stack += ` {\n${renderErrorCause(cause.cause as PrettyError, `${prefix} `)}\n${prefix}}`
893+
stack += ` {\n${renderErrorCause(cause.cause as Cause.PrettyError, `${prefix} `)}\n${prefix}}`
894894
}
895895
return stack
896896
}
897897

898898
/** @internal */
899-
export class PrettyError extends globalThis.Error implements Cause.PrettyError {
900-
span: undefined | Span = undefined
901-
constructor(originalError: unknown) {
902-
const originalErrorIsObject = typeof originalError === "object" && originalError !== null
903-
const prevLimit = Error.stackTraceLimit
904-
Error.stackTraceLimit = 1
905-
super(
906-
prettyErrorMessage(originalError),
907-
originalErrorIsObject && "cause" in originalError && typeof originalError.cause !== "undefined"
908-
? { cause: new PrettyError(originalError.cause) }
909-
: undefined
910-
)
911-
if (this.message === "") {
912-
this.message = "An error has occurred"
899+
export const makePrettyError = (originalError: unknown): Cause.PrettyError => {
900+
const originalErrorIsObject = typeof originalError === "object" && originalError !== null
901+
const prevLimit = Error.stackTraceLimit
902+
Error.stackTraceLimit = 1
903+
const error = new Error(
904+
prettyErrorMessage(originalError),
905+
originalErrorIsObject && "cause" in originalError && typeof originalError.cause !== "undefined"
906+
? { cause: makePrettyError(originalError.cause) }
907+
: undefined
908+
) as Types.Mutable<Cause.PrettyError>
909+
Error.stackTraceLimit = prevLimit
910+
if (error.message === "") {
911+
error.message = "An error has occurred"
912+
}
913+
Error.stackTraceLimit = prevLimit
914+
error.name = originalError instanceof Error ? originalError.name : "Error"
915+
if (originalErrorIsObject) {
916+
if (spanSymbol in originalError) {
917+
error.span = originalError[spanSymbol] as Span
913918
}
914-
Error.stackTraceLimit = prevLimit
915-
this.name = originalError instanceof Error ? originalError.name : "Error"
916-
if (originalErrorIsObject) {
917-
if (spanSymbol in originalError) {
918-
this.span = originalError[spanSymbol] as Span
919+
Object.keys(originalError).forEach((key) => {
920+
if (!(key in error)) {
921+
// @ts-expect-error
922+
error[key] = originalError[key]
919923
}
920-
Object.keys(originalError).forEach((key) => {
921-
if (!(key in this)) {
922-
// @ts-expect-error
923-
this[key] = originalError[key]
924-
}
925-
})
926-
}
927-
this.stack = prettyErrorStack(
928-
`${this.name}: ${this.message}`,
929-
originalError instanceof Error && originalError.stack
930-
? originalError.stack
931-
: "",
932-
this.span
933-
)
924+
})
934925
}
926+
error.stack = prettyErrorStack(
927+
`${error.name}: ${error.message}`,
928+
originalError instanceof Error && originalError.stack
929+
? originalError.stack
930+
: "",
931+
error.span
932+
)
933+
return error
935934
}
936935

937936
/**
@@ -1035,14 +1034,14 @@ const prettyErrorStack = (message: string, stack: string, span?: Span | undefine
10351034
export const spanSymbol = Symbol.for("effect/SpanAnnotation")
10361035

10371036
/** @internal */
1038-
export const prettyErrors = <E>(cause: Cause.Cause<E>): Array<PrettyError> =>
1037+
export const prettyErrors = <E>(cause: Cause.Cause<E>): Array<Cause.PrettyError> =>
10391038
reduceWithContext(cause, void 0, {
1040-
emptyCase: (): Array<PrettyError> => [],
1039+
emptyCase: (): Array<Cause.PrettyError> => [],
10411040
dieCase: (_, unknownError) => {
1042-
return [new PrettyError(unknownError)]
1041+
return [makePrettyError(unknownError)]
10431042
},
10441043
failCase: (_, error) => {
1045-
return [new PrettyError(error)]
1044+
return [makePrettyError(error)]
10461045
},
10471046
interruptCase: () => [],
10481047
parallelCase: (_, l, r) => [...l, ...r],

packages/effect/src/internal/logger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ const prettyLoggerBrowser = (options: {
456456
console.groupCollapsed(firstLine, ...firstParams)
457457

458458
if (!Cause.isEmpty(cause)) {
459-
console.error(Cause.pretty(cause, { renderErrorCause: true }))
459+
console.error(...Cause.prettyErrors(cause))
460460
}
461461

462462
if (messageIndex < message.length) {

packages/effect/test/Cause.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -926,16 +926,16 @@ describe("Cause", () => {
926926
describe("Formatting", () => {
927927
it("prettyErrors", () => {
928928
deepStrictEqual(Cause.prettyErrors(empty), [])
929-
deepStrictEqual(Cause.prettyErrors(failure), [new internal.PrettyError("error")])
930-
deepStrictEqual(Cause.prettyErrors(defect), [new internal.PrettyError("defect")])
929+
deepStrictEqual(Cause.prettyErrors(failure), [internal.makePrettyError("error")])
930+
deepStrictEqual(Cause.prettyErrors(defect), [internal.makePrettyError("defect")])
931931
deepStrictEqual(Cause.prettyErrors(interruption), [])
932932
deepStrictEqual(Cause.prettyErrors(sequential), [
933-
new internal.PrettyError("error"),
934-
new internal.PrettyError("defect")
933+
internal.makePrettyError("error"),
934+
internal.makePrettyError("defect")
935935
])
936936
deepStrictEqual(Cause.prettyErrors(parallel), [
937-
new internal.PrettyError("error"),
938-
new internal.PrettyError("defect")
937+
internal.makePrettyError("error"),
938+
internal.makePrettyError("defect")
939939
])
940940
})
941941

0 commit comments

Comments
 (0)