Skip to content

Commit 6e8c5aa

Browse files
committed
refactor(error display): use messageWithCauses from @socketsecurity/lib/errors
Replace the hand-rolled cause-chain walker with the socket-lib re-export (originally pony-cause). Benefits: - Single source of truth for cause formatting across CLI + lib. - Proper cycle detection via a `seen` Set instead of a depth-5 cap that could silently truncate legitimate 5+ level chains. - api.mts drops its direct `pony-cause` import for the same re-export. - Removes `pony-cause` from root and cli devDependencies (it was imported in runtime code, a latent classification bug — socket-lib bundles it internally so direct dependence was never needed). Test updated to assert cycle termination instead of depth cap.
1 parent 8ebd9cc commit 6e8c5aa

File tree

7 files changed

+20
-36
lines changed

7 files changed

+20
-36
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@
121121
"oxfmt": "0.37.0",
122122
"oxlint": "1.52.0",
123123
"package-builder": "workspace:*",
124-
"pony-cause": "catalog:",
125124
"postject": "catalog:",
126125
"registry-auth-token": "catalog:",
127126
"registry-url": "catalog:",

packages/cli/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@
110110
"npm-package-arg": "catalog:",
111111
"open": "catalog:",
112112
"package-builder": "workspace:*",
113-
"pony-cause": "catalog:",
114113
"registry-auth-token": "catalog:",
115114
"registry-url": "catalog:",
116115
"semver": "catalog:",

packages/cli/src/utils/error/display.mts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import colors from 'yoctocolors-cjs'
44

5+
import { messageWithCauses } from '@socketsecurity/lib/errors'
56
import { LOG_SYMBOLS } from '@socketsecurity/lib/logger'
67
import { stripAnsi } from '@socketsecurity/lib/strings'
78

@@ -26,22 +27,18 @@ export type ErrorDisplayOptions = {
2627
}
2728

2829
/**
29-
* Append the `.cause` chain (up to 5 levels) to a base message so
30-
* non-debug users see the diagnostic context from wrapped errors.
31-
* Typed errors (AuthError, NetworkError, …) can also carry causes.
30+
* Append the `.cause` chain to a decorated base message. Typed errors
31+
* build their message with suffixes (e.g. ` (HTTP 500)`) before this
32+
* is called, so we can't just `messageWithCauses(error)` — we decorate
33+
* first, then delegate cause walking to socket-lib.
3234
*/
3335
function appendCauseChain(baseMessage: string, cause: unknown): string {
34-
const plainCauses: string[] = []
35-
let walk: unknown = cause
36-
let walkDepth = 1
37-
while (walk && walkDepth <= 5) {
38-
plainCauses.push(walk instanceof Error ? walk.message : String(walk))
39-
walk = walk instanceof Error ? walk.cause : undefined
40-
walkDepth++
36+
if (!cause) {
37+
return baseMessage
4138
}
42-
return plainCauses.length
43-
? `${baseMessage}: ${plainCauses.join(': ')}`
44-
: baseMessage
39+
const causeText =
40+
cause instanceof Error ? messageWithCauses(cause) : String(cause)
41+
return `${baseMessage}: ${causeText}`
4542
}
4643

4744
/**

packages/cli/src/utils/socket/api.mts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@
1919
* - Falls back to configured apiBaseUrl or default API_V0_URL
2020
*/
2121

22-
import { messageWithCauses } from 'pony-cause'
23-
2422
import { debug, debugDir } from '@socketsecurity/lib/debug'
2523
import { getSocketCliApiBaseUrl } from '@socketsecurity/lib/env/socket-cli'
24+
import { messageWithCauses } from '@socketsecurity/lib/errors'
2625
import { httpRequest } from '@socketsecurity/lib/http-request'
2726
import { getDefaultLogger } from '@socketsecurity/lib/logger'
2827
import { getDefaultSpinner } from '@socketsecurity/lib/spinner'

packages/cli/test/unit/utils/error/display.test.mts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,17 @@ describe('error/display', () => {
162162
expect(result.message).toContain('root DNS failure')
163163
})
164164

165-
it('stops walking causes at depth 5 to avoid runaway chains', () => {
166-
let e: Error | undefined
167-
for (let i = 0; i <= 10; i++) {
168-
e = new Error(`level-${i}`, e ? { cause: e } : undefined)
169-
}
165+
it('terminates on cyclic cause chains', () => {
166+
const a = new Error('a')
167+
const b = new Error('b')
168+
;(a as Error & { cause?: unknown }).cause = b
169+
;(b as Error & { cause?: unknown }).cause = a
170170

171-
const result = formatErrorForDisplay(e!)
171+
const result = formatErrorForDisplay(a)
172172

173-
expect(result.message).toContain('level-10')
174-
expect(result.message).toContain('level-5')
175-
expect(result.message).not.toContain('level-4')
173+
expect(result.message).toContain('a')
174+
expect(result.message).toContain('b')
175+
expect(result.message).toContain('...')
176176
})
177177

178178
it('uses custom title when provided', () => {

pnpm-lock.yaml

Lines changed: 0 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ catalog:
116116
oxlint: 1.52.0
117117
packageurl-js: npm:@socketregistry/packageurl-js@^1.4.2
118118
path-parse: npm:@socketregistry/path-parse@^1.0.8
119-
pony-cause: 2.1.11
120119
postject: 1.0.0-alpha.6
121120
react: 19.2.0
122121
react-reconciler: 0.33.0

0 commit comments

Comments
 (0)