Skip to content

Commit 91abea0

Browse files
authored
fix: improve error logging when failing to parse config file (#1423)
1 parent 31a1f95 commit 91abea0

File tree

6 files changed

+186
-18
lines changed

6 files changed

+186
-18
lines changed

.changeset/smart-pets-melt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'lint-staged': patch
3+
---
4+
5+
Improve error logging when failing to read or parse a configuration file

lib/loadConfig.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import debug from 'debug'
77
import YAML from 'yaml'
88

99
import { dynamicImport } from './dynamicImport.js'
10+
import { failedToLoadConfig } from './messages.js'
1011
import { resolveConfig } from './resolveConfig.js'
1112
import {
1213
CONFIG_FILE_NAMES,
@@ -117,8 +118,8 @@ export const loadConfig = async ({ configPath, cwd }, logger) => {
117118

118119
return { config, filepath }
119120
} catch (error) {
120-
debugLog('Failed to load configuration!')
121-
logger.error(error)
121+
debugLog('Failed to load configuration from `%s` with error:\n', configPath, error)
122+
logger.error(failedToLoadConfig(configPath))
122123
return {}
123124
}
124125
}

lib/messages.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,15 @@ export const RESTORE_STASH_EXAMPLE = ` Any lost modifications can be restored f
8585
`
8686

8787
export const CONFIG_STDIN_ERROR = chalk.redBright(`${error} Failed to read config from stdin.`)
88+
89+
export const failedToLoadConfig = (filepath) =>
90+
chalk.redBright(`${error} Failed to read config from file "${filepath}".`)
91+
92+
export const failedToParseConfig = (
93+
filepath,
94+
error
95+
) => `${chalk.redBright(`${error} Failed to parse config from file "${filepath}".`)}
96+
97+
${error}
98+
99+
See https://github.com/okonet/lint-staged#configuration.`

lib/validateConfig.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { inspect } from 'node:util'
44

55
import debug from 'debug'
66

7-
import { configurationError } from './messages.js'
7+
import { configurationError, failedToParseConfig } from './messages.js'
88
import { ConfigEmptyError, ConfigFormatError } from './symbols.js'
99
import { validateBraces } from './validateBraces.js'
1010

@@ -23,14 +23,7 @@ const TEST_DEPRECATED_KEYS = new Map([
2323
['relative', (key) => typeof key === 'boolean'],
2424
])
2525

26-
/**
27-
* Runs config validation. Throws error if the config is not valid.
28-
* @param {Object} config
29-
* @param {string} configPath
30-
* @param {Logger} logger
31-
* @returns {Object} config
32-
*/
33-
export const validateConfig = (config, configPath, logger) => {
26+
export const validateConfigLogic = (config, configPath, logger) => {
3427
debugLog('Validating config from `%s`...', configPath)
3528

3629
if (!config || (typeof config !== 'object' && typeof config !== 'function')) {
@@ -100,11 +93,7 @@ export const validateConfig = (config, configPath, logger) => {
10093
if (errors.length) {
10194
const message = errors.join('\n\n')
10295

103-
logger.error(`Could not parse lint-staged config.
104-
105-
${message}
106-
107-
See https://github.com/okonet/lint-staged#configuration.`)
96+
logger.error(failedToParseConfig(configPath, message))
10897

10998
throw new Error(message)
11099
}
@@ -114,3 +103,19 @@ See https://github.com/okonet/lint-staged#configuration.`)
114103

115104
return validatedConfig
116105
}
106+
107+
/**
108+
* Runs config validation. Throws error if the config is not valid.
109+
* @param {Object} config
110+
* @param {string} configPath
111+
* @param {Logger} logger
112+
* @returns {Object} config
113+
*/
114+
export const validateConfig = (config, configPath, logger) => {
115+
try {
116+
return validateConfigLogic(config, configPath, logger)
117+
} catch (error) {
118+
logger.error(failedToParseConfig(configPath, error))
119+
throw error
120+
}
121+
}

test/unit/__snapshots__/validateConfig.spec.js.snap

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,153 @@ exports[`validateConfig should throw when detecting deprecated advanced configur
6464

6565
exports[`validateConfig should throw when detecting deprecated advanced configuration 2`] = `
6666
"
67-
ERROR Could not parse lint-staged config.
67+
ERROR ✖ Validation Error:
68+
69+
Invalid value for 'chunkSize': 10
70+
71+
Advanced configuration has been deprecated.
72+
73+
✖ Validation Error:
74+
75+
Invalid value for 'concurrent': false
76+
77+
Advanced configuration has been deprecated.
78+
79+
✖ Validation Error:
80+
81+
Invalid value for 'globOptions': { matchBase: false }
82+
83+
Advanced configuration has been deprecated.
84+
85+
✖ Validation Error:
86+
87+
Invalid value for 'ignore': [ 'test.js' ]
88+
89+
Advanced configuration has been deprecated.
90+
91+
✖ Validation Error:
92+
93+
Invalid value for 'linters': { '*.js': [ 'eslint' ] }
94+
95+
Advanced configuration has been deprecated.
96+
97+
✖ Validation Error:
98+
99+
Invalid value for 'relative': true
100+
101+
Advanced configuration has been deprecated.
102+
103+
✖ Validation Error:
104+
105+
Invalid value for 'renderer': 'silent'
106+
107+
Advanced configuration has been deprecated.
108+
109+
✖ Validation Error:
110+
111+
Invalid value for 'subTaskConcurrency': 10
112+
113+
Advanced configuration has been deprecated. Failed to parse config from file ".lintstagedrc.json".
114+
115+
✖ Validation Error:
116+
117+
Invalid value for 'chunkSize': 10
118+
119+
Advanced configuration has been deprecated.
120+
121+
✖ Validation Error:
122+
123+
Invalid value for 'concurrent': false
124+
125+
Advanced configuration has been deprecated.
126+
127+
✖ Validation Error:
128+
129+
Invalid value for 'globOptions': { matchBase: false }
130+
131+
Advanced configuration has been deprecated.
132+
133+
✖ Validation Error:
134+
135+
Invalid value for 'ignore': [ 'test.js' ]
136+
137+
Advanced configuration has been deprecated.
68138
69139
✖ Validation Error:
70140
141+
Invalid value for 'linters': { '*.js': [ 'eslint' ] }
142+
143+
Advanced configuration has been deprecated.
144+
145+
✖ Validation Error:
146+
147+
Invalid value for 'relative': true
148+
149+
Advanced configuration has been deprecated.
150+
151+
✖ Validation Error:
152+
153+
Invalid value for 'renderer': 'silent'
154+
155+
Advanced configuration has been deprecated.
156+
157+
✖ Validation Error:
158+
159+
Invalid value for 'subTaskConcurrency': 10
160+
161+
Advanced configuration has been deprecated.
162+
163+
See https://github.com/okonet/lint-staged#configuration.
164+
ERROR Error: ✖ Validation Error:
165+
166+
Invalid value for 'chunkSize': 10
167+
168+
Advanced configuration has been deprecated.
169+
170+
✖ Validation Error:
171+
172+
Invalid value for 'concurrent': false
173+
174+
Advanced configuration has been deprecated.
175+
176+
✖ Validation Error:
177+
178+
Invalid value for 'globOptions': { matchBase: false }
179+
180+
Advanced configuration has been deprecated.
181+
182+
✖ Validation Error:
183+
184+
Invalid value for 'ignore': [ 'test.js' ]
185+
186+
Advanced configuration has been deprecated.
187+
188+
✖ Validation Error:
189+
190+
Invalid value for 'linters': { '*.js': [ 'eslint' ] }
191+
192+
Advanced configuration has been deprecated.
193+
194+
✖ Validation Error:
195+
196+
Invalid value for 'relative': true
197+
198+
Advanced configuration has been deprecated.
199+
200+
✖ Validation Error:
201+
202+
Invalid value for 'renderer': 'silent'
203+
204+
Advanced configuration has been deprecated.
205+
206+
✖ Validation Error:
207+
208+
Invalid value for 'subTaskConcurrency': 10
209+
210+
Advanced configuration has been deprecated. Failed to parse config from file ".lintstagedrc.json".
211+
212+
Error: ✖ Validation Error:
213+
71214
Invalid value for 'chunkSize': 10
72215
73216
Advanced configuration has been deprecated.

test/unit/loadConfig.spec.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ describe('loadConfig', () => {
4848
})
4949

5050
it('should not return config when YAML config file is invalid', async () => {
51-
expect.assertions(1)
51+
expect.assertions(2)
5252

5353
const { config } = await loadConfig(
5454
{ configPath: path.join(__dirname, '__mocks__', 'invalid-config-file.yml') },
5555
logger
5656
)
5757

58+
expect(logger.printHistory()).toMatch('Failed to read config from file')
59+
5860
expect(config).toBeUndefined()
5961
})
6062

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy