Skip to content

Commit c31f3a2

Browse files
committed
refactor: standardize errors
1 parent 461760a commit c31f3a2

File tree

13 files changed

+82
-36
lines changed

13 files changed

+82
-36
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@pandacss/types': patch
3+
'@pandacss/logger': patch
4+
'@pandacss/shared': patch
5+
'@pandacss/cli': patch
6+
'@pandacss/core': patch
7+
'@pandacss/config': patch
8+
'@pandacss/node': patch
9+
'@pandacss/generator': patch
10+
---
11+
12+
Improve error handling architecture across all packages.

packages/cli/src/cli-main.ts

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,9 @@ export async function main() {
367367
const studioPath = require.resolve('@pandacss/studio', { paths: [cwd] })
368368
studio = require(studioPath)
369369
} catch (error) {
370-
logger.error('studio', error)
371-
throw new PandaError('MISSING_STUDIO', "You need to install '@pandacss/studio' to use this command")
370+
throw new PandaError('MISSING_STUDIO', "You need to install '@pandacss/studio' to use this command", {
371+
cause: error,
372+
})
372373
}
373374

374375
if (preview) {
@@ -666,20 +667,5 @@ export async function main() {
666667
cli.version(version)
667668

668669
cli.parse(process.argv, { run: false })
669-
670-
try {
671-
await cli.runMatchedCommand()
672-
} catch (error) {
673-
if (error instanceof PandaError) {
674-
logger.error('cli', error)
675-
676-
if (logger.isDebug) {
677-
console.error(error)
678-
}
679-
680-
process.exit(1)
681-
}
682-
683-
throw error
684-
}
670+
await cli.runMatchedCommand()
685671
}

packages/cli/src/errors.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,47 @@
11
import { isMainThread, parentPort } from 'worker_threads'
22
import colors from 'kleur'
3+
import { PandaError } from '@pandacss/shared'
34

4-
export function handleError(error: any) {
5-
if (error.loc) {
5+
export function handleError(error: unknown) {
6+
if (error instanceof PandaError) {
7+
console.error(colors.red(`${error.code}: ${error.message}`))
8+
if (error.hint) {
9+
console.error(colors.dim(error.hint))
10+
}
11+
if (error.cause instanceof Error) {
12+
console.error(colors.dim(`Caused by: ${error.cause.message}`))
13+
}
14+
} else if (isLocError(error)) {
615
console.error(colors.bold(colors.red(`Error parsing: ${error.loc.file}:${error.loc.line}:${error.loc.column}`)))
7-
}
8-
if (error.frame) {
9-
console.error(colors.red(error.message))
10-
console.error(colors.dim(error.frame))
16+
if (error.frame) {
17+
console.error(colors.red(error.message))
18+
console.error(colors.dim(error.frame))
19+
} else {
20+
console.error(colors.red(error.message))
21+
}
1122
} else {
12-
console.error(colors.red(error.message))
23+
const message = error instanceof Error ? error.message : String(error)
24+
console.error(colors.red(message))
1325
}
26+
1427
process.exitCode = 1
1528
if (!isMainThread && parentPort) {
1629
parentPort.postMessage('error')
1730
}
1831
}
32+
33+
interface LocError {
34+
loc: { file: string; line: number; column: number }
35+
frame?: string
36+
message: string
37+
}
38+
39+
function isLocError(error: unknown): error is LocError {
40+
return (
41+
typeof error === 'object' &&
42+
error !== null &&
43+
'loc' in error &&
44+
typeof (error as any).loc === 'object' &&
45+
'message' in error
46+
)
47+
}

packages/config/src/merge-hooks.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ const tryCatch = (name: string, fn: AnyFunction) => {
170170
try {
171171
return fn(...args)
172172
} catch (e) {
173-
logger.error('hooks', `The error below comes from the plugin ${name}`)
174-
console.error(e)
173+
logger.caughtError('hooks', `Error in plugin "${name}"`, e)
175174
}
176175
}
177176
}

packages/core/src/conditions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,9 @@ export class Conditions {
184184
try {
185185
return parseCondition(condNameOrQuery)
186186
} catch (error) {
187-
logger.error('core:condition', error)
187+
const query = typeof condNameOrQuery === 'string' ? condNameOrQuery : JSON.stringify(condNameOrQuery)
188+
const message = error instanceof Error ? error.message : String(error)
189+
logger.warn('core:condition', `Failed to parse condition "${query}": ${message}`)
188190
}
189191
}
190192

packages/core/src/stylesheet.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ export class Stylesheet {
3535
} catch (error) {
3636
if (error instanceof CssSyntaxError) {
3737
logger.error('sheet:process', error.showSourceCode(true))
38+
} else {
39+
logger.caughtError('sheet:process', 'Failed to process styles', error)
3840
}
3941
}
4042
return

packages/generator/src/artifacts/css/parser-css.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export const generateParserCss = (ctx: Context, decoder: StyleDecoder) => {
1313
try {
1414
const css = sheet.toCss({ minify })
1515
return css
16-
} catch (err) {
17-
logger.error('serializer:css', 'Failed to serialize CSS: ' + err)
16+
} catch (error) {
17+
logger.caughtError('serializer:css', 'Failed to serialize CSS', error)
1818
return ''
1919
}
2020
}

packages/generator/src/artifacts/css/token-css.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ const parse = (str: string) => {
123123
} catch (error) {
124124
if (error instanceof CssSyntaxError) {
125125
logger.error('tokens:process', error.showSourceCode(true))
126+
} else {
127+
logger.caughtError('tokens:process', 'Failed to parse token CSS', error)
126128
}
127129
}
128130
}

packages/logger/src/create-logger.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ export const createLogger = (conf: LoggerConfig = {}): LoggerInterface => {
5252
}
5353
}
5454

55+
const caughtError = (type: string, context: string, error: unknown) => {
56+
const message = error instanceof Error ? error.message : String(error)
57+
logFns.error(type, `${context}: ${message}`)
58+
if (error instanceof Error && error.stack) {
59+
logFns.debug(type, error.stack)
60+
}
61+
}
62+
5563
return {
5664
get level() {
5765
return level
@@ -63,6 +71,7 @@ export const createLogger = (conf: LoggerConfig = {}): LoggerInterface => {
6371
onLog = fn
6472
},
6573
...logFns,
74+
caughtError,
6675
print(data: any) {
6776
console.dir(data, { depth: null, colors: true })
6877
},

packages/node/src/create-context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export class PandaContext extends Generator {
7575
const encoder = styleEncoder || this.parserOptions.encoder
7676
result = this.project.parseSourceFile(file, encoder)
7777
} catch (error) {
78-
logger.error('file:extract', error)
78+
logger.caughtError('file:extract', `Failed to parse ${file}`, error)
7979
}
8080

8181
measure()

0 commit comments

Comments
 (0)