@@ -31,19 +31,35 @@ export class Settings {
31
31
) { }
32
32
33
33
/**
34
- * Reads a setting, applying the {@link TypeConstructor} if provided.
34
+ * Gets a setting value , applying the {@link TypeConstructor} if provided.
35
35
*
36
- * Note that the absence of a key is indistinguisable from the absence of a value.
37
- * That is, `undefined` looks the same across all calls. Any non-existent values are
38
- * simply returned as-is without passing through the type cast.
36
+ * If the read fails or the setting value is invalid (does not conform to `type`):
37
+ * - `defaultValue` is returned if it was provided
38
+ * - else an exception is thrown
39
+ *
40
+ * @note An unknown setting is indistinguisable from a missing value: both return `undefined`.
41
+ * Non-existent values are returned as-is without passing through the type cast.
42
+ *
43
+ * @param key Setting name
44
+ * @param type Expected setting type
45
+ * @param defaultValue Value returned if setting is missing or invalid
39
46
*/
40
47
public get ( key : string ) : unknown
41
48
public get < T > ( key : string , type : TypeConstructor < T > ) : T | undefined
42
49
public get < T > ( key : string , type : TypeConstructor < T > , defaultValue : T ) : T
43
50
public get < T > ( key : string , type ?: TypeConstructor < T > , defaultValue ?: T ) {
44
- const value = this . getConfig ( ) . get ( key , defaultValue )
51
+ try {
52
+ const value = this . getConfig ( ) . get ( key , defaultValue )
45
53
46
- return ! type || value === undefined ? value : cast ( value , type )
54
+ return ! type || value === undefined ? value : cast ( value , type )
55
+ } catch ( e ) {
56
+ if ( arguments . length <= 2 ) {
57
+ throw ToolkitError . chain ( e , `Failed to read setting "${ key } "` )
58
+ }
59
+ getLogger ( ) . error ( 'settings: failed to read "%s": %s' , key , ( e as Error ) . message )
60
+
61
+ return defaultValue
62
+ }
47
63
}
48
64
49
65
/**
@@ -62,8 +78,8 @@ export class Settings {
62
78
await this . getConfig ( ) . update ( key , value , this . updateTarget )
63
79
64
80
return true
65
- } catch ( error ) {
66
- getLogger ( ) . warn ( `Settings : failed to update "${ key } ": %s` , error )
81
+ } catch ( e ) {
82
+ getLogger ( ) . warn ( 'settings : failed to update "%s ": %s' , key , ( e as Error ) . message )
67
83
68
84
return false
69
85
}
@@ -151,7 +167,8 @@ export class Settings {
151
167
* The resulting configuration object should not be cached.
152
168
*/
153
169
private getConfig ( section ?: string ) {
154
- return this . workspace . getConfiguration ( section , this . scope )
170
+ // eslint-disable-next-line no-null/no-null
171
+ return this . workspace . getConfiguration ( section , this . scope ?? null )
155
172
}
156
173
157
174
/**
@@ -167,7 +184,7 @@ export class Settings {
167
184
static #instance: Settings
168
185
169
186
/**
170
- * A singleton scoped to the global configuration target.
187
+ * A singleton scoped to the global configuration target and `null` resource .
171
188
*/
172
189
public static get instance ( ) {
173
190
return ( this . #instance ??= new this ( ) )
@@ -223,15 +240,24 @@ function createSettingsClass<T extends TypeDescriptor>(section: string, descript
223
240
return this . config . keys ( )
224
241
}
225
242
243
+ /**
244
+ * Gets a setting value.
245
+ *
246
+ * If the read fails or the setting value is invalid (does not conform to the type defined in package.json):
247
+ * - `defaultValue` is returned if it was provided
248
+ * - else an exception is thrown
249
+ *
250
+ * @param key Setting name
251
+ * @param defaultValue Value returned if setting is missing or invalid
252
+ */
226
253
public get < K extends keyof Inner > ( key : K & string , defaultValue ?: Inner [ K ] ) {
227
254
try {
228
255
return this . getOrThrow ( key , defaultValue )
229
256
} catch ( e ) {
230
257
if ( arguments . length === 1 ) {
231
258
throw ToolkitError . chain ( e , `Failed to read key "${ section } .${ key } "` )
232
259
}
233
-
234
- this . logErr ( `using default for key "${ key } ", read failed: %s` , e )
260
+ this . logErr ( 'failed to read "%s": %s' , key , ( e as Error ) . message )
235
261
236
262
return defaultValue as Inner [ K ]
237
263
}
@@ -242,8 +268,8 @@ function createSettingsClass<T extends TypeDescriptor>(section: string, descript
242
268
await this . config . update ( key , value )
243
269
244
270
return true
245
- } catch ( error ) {
246
- this . log ( ` failed to update field " ${ key } ": %s` , error )
271
+ } catch ( e ) {
272
+ this . log ( ' failed to update "%s ": %s' , key , ( e as Error ) . message )
247
273
248
274
return false
249
275
}
@@ -254,8 +280,8 @@ function createSettingsClass<T extends TypeDescriptor>(section: string, descript
254
280
await this . config . update ( key , undefined )
255
281
256
282
return true
257
- } catch ( error ) {
258
- this . log ( ` failed to delete field " ${ key } ": %s` , error )
283
+ } catch ( e ) {
284
+ this . log ( ' failed to delete "%s ": %s' , key , ( e as Error ) . message )
259
285
260
286
return false
261
287
}
@@ -264,8 +290,8 @@ function createSettingsClass<T extends TypeDescriptor>(section: string, descript
264
290
public async reset ( ) {
265
291
try {
266
292
return await this . config . reset ( )
267
- } catch ( error ) {
268
- this . log ( ` failed to reset settings: %s` , error )
293
+ } catch ( e ) {
294
+ this . log ( ' failed to reset settings: %s' , ( e as Error ) . message )
269
295
}
270
296
}
271
297
@@ -316,7 +342,7 @@ function createSettingsClass<T extends TypeDescriptor>(section: string, descript
316
342
}
317
343
318
344
for ( const key of props . filter ( isDifferent ) ) {
319
- this . log ( ` key "${ key } " changed` )
345
+ this . log ( ' key "%s " changed' , key )
320
346
emitter . fire ( { key } )
321
347
}
322
348
} )
@@ -508,8 +534,8 @@ export class PromptSettings extends Settings.define(
508
534
public async isPromptEnabled ( promptName : PromptName ) : Promise < boolean > {
509
535
try {
510
536
return ! this . getOrThrow ( promptName , false )
511
- } catch ( error ) {
512
- this . log ( ` prompt check for "${ promptName } " failed: %s` , error )
537
+ } catch ( e ) {
538
+ this . log ( ' prompt check for "%s " failed: %s' , promptName , ( e as Error ) . message )
513
539
await this . reset ( )
514
540
515
541
return true
0 commit comments