Skip to content

Commit a1b7a8f

Browse files
Merge branch 'implement-AggregateException-for-ParseSettingsHashtable_Hashtable' into aggregate-settings-file-exceptions
2 parents dca15a8 + 09222c6 commit a1b7a8f

File tree

1 file changed

+114
-48
lines changed

1 file changed

+114
-48
lines changed

Engine/Settings.cs

Lines changed: 114 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,14 @@ private bool IsStringOrStringArray(object val)
252252
return val == null ? false : valArr.All(x => x is string);
253253
}
254254

255-
private List<string> ParseSettingValueStringOrStrings(object value, string settingName)
255+
private List<string> ParseSettingValueStringOrStrings(object value, string settingName, IList<Exception> exceptions)
256256
{
257257
if (value == null)
258258
{
259-
throw new InvalidDataException(string.Format(
259+
exceptions.Add(new InvalidDataException(string.Format(
260260
Strings.SettingValueIsNull,
261-
settingName));
261+
settingName)));
262+
return null;
262263
}
263264

264265
if (value is string)
@@ -268,9 +269,10 @@ private List<string> ParseSettingValueStringOrStrings(object value, string setti
268269

269270
if (!(value is ICollection))
270271
{
271-
throw new InvalidDataException(string.Format(
272+
exceptions.Add(new InvalidDataException(string.Format(
272273
Strings.SettingValueIsNotStringOrStringsType,
273-
settingName));
274+
settingName)));
275+
return null;
274276
}
275277
var values = value as ICollection;
276278

@@ -280,19 +282,21 @@ private List<string> ParseSettingValueStringOrStrings(object value, string setti
280282
{
281283
if (element is null)
282284
{
283-
throw new InvalidDataException(string.Format(
285+
exceptions.Add(new InvalidDataException(string.Format(
284286
Strings.SettingValueElementIsNull,
285287
settingName,
286-
elementIndex));
288+
elementIndex)));
289+
continue;
287290
}
288291

289292
if (!(element is string))
290293
{
291-
throw new InvalidDataException(string.Format(
294+
exceptions.Add(new InvalidDataException(string.Format(
292295
Strings.SettingValueElementIsNotStringType,
293296
settingName,
294297
elementIndex,
295-
element));
298+
element)));
299+
continue;
296300
}
297301
strings.Add(element as string);
298302

@@ -302,92 +306,138 @@ private List<string> ParseSettingValueStringOrStrings(object value, string setti
302306
return strings;
303307
}
304308

305-
private bool ParseSettingValueBoolean(object value, string settingName)
309+
private bool? ParseSettingValueBoolean(object value, string settingName, IList<Exception> exceptions)
306310
{
307311
if (value == null)
308312
{
309-
throw new InvalidDataException(string.Format(
313+
exceptions.Add(new InvalidDataException(string.Format(
310314
Strings.SettingValueIsNull,
311-
settingName));
315+
settingName)));
316+
return null;
312317
}
313318

314319
if (!(value is bool))
315320
{
316-
throw new InvalidDataException(string.Format(
321+
exceptions.Add(new InvalidDataException(string.Format(
317322
Strings.SettingValueIsNotBooleanType,
318323
settingName,
319-
value));
324+
value)));
325+
return null;
320326
}
321327

322328
return (bool) value;
323329
}
324330

325331
private void ParseSettingsHashtable(Hashtable settings)
326332
{
333+
IList<Exception> exceptions = new List<Exception>();
334+
327335
ISet<string> uniqueSettingKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
328336
foreach (DictionaryEntry setting in settings)
329337
{
330338
if (setting.Key is null)
331339
{
332-
throw new InvalidDataException(Strings.SettingKeyIsNull);
340+
exceptions.Add(new InvalidDataException(
341+
Strings.SettingKeyIsNull));
342+
continue;
333343
}
334344

335345
if (!(setting.Key is string))
336346
{
337-
throw new InvalidDataException(string.Format(
347+
exceptions.Add(new InvalidDataException(string.Format(
338348
Strings.SettingKeyIsNotStringType,
339-
setting.Key));
349+
setting.Key)));
350+
continue;
340351
}
341352
string settingName = setting.Key as string;
342353

343354
if (!uniqueSettingKeys.Add(settingName))
344355
{
345356
// setting.Key should be used instead of settingName because the former preserves information about the source casing.
346-
throw new InvalidDataException(string.Format(
357+
exceptions.Add(new InvalidDataException(string.Format(
347358
Strings.SettingKeyIsNotUniqueIgnoringCase,
348-
setting.Key));
359+
setting.Key)));
360+
continue;
349361
}
350362

351363
if (setting.Value is null)
352364
{
353-
throw new InvalidDataException(string.Format(
365+
exceptions.Add(new InvalidDataException(string.Format(
354366
Strings.SettingValueIsNull,
355-
settingName));
367+
settingName)));
368+
continue;
356369
}
357370

358371
// ToLowerInvariant is important to also work with turkish culture, see https://github.com/PowerShell/PSScriptAnalyzer/issues/1095
359372
switch (settingName.ToLowerInvariant())
360373
{
361374
case "severity":
362-
this.severities = ParseSettingValueStringOrStrings(setting.Value, settingName);
375+
var maybeSeverity = ParseSettingValueStringOrStrings(setting.Value, settingName, exceptions);
376+
if (maybeSeverity is null)
377+
{
378+
continue;
379+
}
380+
381+
this.severities = maybeSeverity;
363382
break;
364383

365384
case "includerules":
366-
this.includeRules = ParseSettingValueStringOrStrings(setting.Value, settingName);
385+
var maybeIncludeRules = ParseSettingValueStringOrStrings(setting.Value, settingName, exceptions);
386+
if (maybeIncludeRules is null)
387+
{
388+
continue;
389+
}
390+
391+
this.includeRules = maybeIncludeRules;
367392
break;
368393

369394
case "excluderules":
370-
this.excludeRules = ParseSettingValueStringOrStrings(setting.Value, settingName);
395+
var maybeExcludeRules = ParseSettingValueStringOrStrings(setting.Value, settingName, exceptions);
396+
if (maybeExcludeRules is null)
397+
{
398+
continue;
399+
}
400+
401+
this.excludeRules = maybeExcludeRules;
371402
break;
372403

373404
case "customrulepath":
374-
this.customRulePath = ParseSettingValueStringOrStrings(setting.Value, settingName);
405+
var maybeCustomRulePath = ParseSettingValueStringOrStrings(setting.Value, settingName, exceptions);
406+
if (maybeCustomRulePath is null)
407+
{
408+
continue;
409+
}
410+
411+
this.customRulePath = maybeCustomRulePath;
375412
break;
376413

377414
case "includedefaultrules":
378-
this.includeDefaultRules = ParseSettingValueBoolean(setting.Value, settingName);
415+
bool? maybeIncludeDefaultRules = ParseSettingValueBoolean(setting.Value, settingName, exceptions);
416+
if (maybeIncludeDefaultRules is null)
417+
{
418+
continue;
419+
}
420+
421+
this.includeDefaultRules = (bool) maybeIncludeDefaultRules;
379422
break;
380423

381424
case "recursecustomrulepath":
382-
this.recurseCustomRulePath = ParseSettingValueBoolean(setting.Value, settingName);
425+
bool? maybeRecurseCustomRulePath = ParseSettingValueBoolean(setting.Value, settingName, exceptions);
426+
if (maybeRecurseCustomRulePath is null)
427+
{
428+
continue;
429+
}
430+
431+
this.recurseCustomRulePath = (bool) maybeRecurseCustomRulePath;
383432
break;
384433

385434
case "rules":
386435
if (!(setting.Value is System.Collections.IDictionary))
387436
{
388-
throw new InvalidDataException(string.Format(
437+
exceptions.Add(new InvalidDataException(string.Format(
389438
Strings.SettingRulesValueIsNotDictionaryType,
390-
setting.Value));
439+
setting.Value)));
440+
continue;
391441
}
392442
Hashtable rules = setting.Value as Hashtable;
393443

@@ -397,38 +447,44 @@ private void ParseSettingsHashtable(Hashtable settings)
397447
{
398448
if (rule.Key is null)
399449
{
400-
throw new InvalidDataException(Strings.SettingRuleKeyIsNull);
450+
exceptions.Add(new InvalidDataException(
451+
Strings.SettingRuleKeyIsNull));
452+
continue;
401453
}
402454

403455
if (!(rule.Key is string))
404456
{
405-
throw new InvalidDataException(string.Format(
457+
exceptions.Add(new InvalidDataException(string.Format(
406458
Strings.SettingRuleKeyIsNotStringType,
407-
rule.Key));
459+
rule.Key)));
460+
continue;
408461
}
409462
string ruleName = rule.Key as string;
410463

411464
if (!uniqueRuleKeys.Add(ruleName))
412465
{
413466
// rule.Key should be used instead of ruleName because the former preserves information about the source casing.
414-
throw new InvalidDataException(string.Format(
467+
exceptions.Add(new InvalidDataException(string.Format(
415468
Strings.SettingRuleKeyIsNotUniqueIgnoringCase,
416-
rule.Key));
469+
rule.Key)));
470+
continue;
417471
}
418472

419473
if (rule.Value is null)
420474
{
421-
throw new InvalidDataException(string.Format(
475+
exceptions.Add(new InvalidDataException(string.Format(
422476
Strings.SettingRuleValueIsNull,
423-
ruleName));
477+
ruleName)));
478+
continue;
424479
}
425480

426481
if (!(rule.Value is System.Collections.IDictionary))
427482
{
428-
throw new InvalidDataException(string.Format(
483+
exceptions.Add(new InvalidDataException(string.Format(
429484
Strings.SettingRuleValueIsNotDictionaryType,
430485
ruleName,
431-
rule.Value));
486+
rule.Value)));
487+
continue;
432488
}
433489
Hashtable arguments = rule.Value as Hashtable;
434490

@@ -438,35 +494,39 @@ private void ParseSettingsHashtable(Hashtable settings)
438494
{
439495
if (argument.Key is null)
440496
{
441-
throw new InvalidDataException(string.Format(
497+
exceptions.Add(new InvalidDataException(string.Format(
442498
Strings.SettingRuleArgumentKeyIsNull,
443-
ruleName));
499+
ruleName)));
500+
continue;
444501
}
445502

446503
if (!(argument.Key is string))
447504
{
448-
throw new InvalidDataException(string.Format(
505+
exceptions.Add(new InvalidDataException(string.Format(
449506
Strings.SettingRuleArgumentKeyIsNotStringType,
450507
ruleName,
451-
argument.Key));
508+
argument.Key)));
509+
continue;
452510
}
453511
string argumentName = argument.Key as string;
454512

455513
if (!uniqueArgumentKeys.Add(argumentName))
456514
{
457515
// argument.Key should be used instead of argumentName because the former preserves information about the source casing.
458-
throw new InvalidDataException(string.Format(
516+
exceptions.Add(new InvalidDataException(string.Format(
459517
Strings.SettingRuleArgumentKeyIsNotUniqueIgnoringCase,
460518
ruleName,
461-
argument.Key));
519+
argument.Key)));
520+
continue;
462521
}
463522

464523
if (argument.Value is null)
465524
{
466-
throw new InvalidDataException(string.Format(
525+
exceptions.Add(new InvalidDataException(string.Format(
467526
Strings.SettingRuleArgumentValueIsNull,
468527
ruleName,
469-
argumentName));
528+
argumentName)));
529+
continue;
470530
}
471531

472532
parsedArguments[argumentName] = argument.Value;
@@ -479,11 +539,17 @@ private void ParseSettingsHashtable(Hashtable settings)
479539
break;
480540

481541
default:
482-
throw new InvalidDataException(string.Format(
542+
exceptions.Add(new InvalidDataException(string.Format(
483543
Strings.WrongKeyHashTable,
484-
settingName));
544+
settingName)));
545+
continue;
485546
}
486547
}
548+
549+
if (exceptions.Count > 0)
550+
{
551+
throw new AggregateException(exceptions);
552+
}
487553
}
488554

489555
private void ParseSettingsFile(string settingsFilePath)

0 commit comments

Comments
 (0)