Skip to content

Commit ce9375b

Browse files
Copilotstephentoub
andauthored
Fix IndexOutOfRangeException to use default message instead of "index" (#120881)
## Summary Multiple classes across the repository were throwing `IndexOutOfRangeException` with `nameof(index)` as the message parameter, resulting in an unhelpful error message of just "index" instead of the standard .NET exception message. ## Changes This PR updates all occurrences to use the parameterless `IndexOutOfRangeException()` constructor, which provides the default, user-friendly message: "Index was outside the bounds of the array." **Before:** ```csharp throw new IndexOutOfRangeException(nameof(index)); // Exception message: "index" ``` **After:** ```csharp throw new IndexOutOfRangeException(); // Exception message: "Index was outside the bounds of the array." ``` ## Files Modified **Logging-related files:** - **LoggerMessage.cs**: Fixed 7 occurrences across different generic `LogValues<T>` classes - **LoggerMessageGenerator.Emitter.cs**: Fixed 1 occurrence in the source generator template - **LogValuesFormatter.cs**: Fixed 1 occurrence in the logging formatter - **FormattedLogValues.cs**: Fixed 1 occurrence in formatted log values - **LoggerExtensionsTest.cs**: Fixed 1 occurrence in test helper class - **HttpHeadersLogValue.cs**: Fixed 1 occurrence in HTTP logging infrastructure - **Baseline test files**: Updated 3 generated code baseline files to match the new output - **LoggerMessageTest.cs**: Added comprehensive test to verify the exception message is proper **Other components:** - **DesignerOptionService.cs**: Fixed 1 occurrence in System.ComponentModel.TypeConverter ## Testing - All existing tests continue to pass (291 tests in Microsoft.Extensions.Logging.Tests, 184 tests in Microsoft.Extensions.Http.Tests) - Added new test `LogValues_OutOfRangeAccess_ThrowsIndexOutOfRangeExceptionWithDefaultMessage` that validates the exception message for all LogValues variants (0-6 parameters) - Manually verified the fix produces the expected error message This is a minimal change that maintains backward compatibility (still throws `IndexOutOfRangeException`) while significantly improving the developer experience with a clear, descriptive error message across the entire codebase. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent 48a162c commit ce9375b

File tree

11 files changed

+59
-16
lines changed

11 files changed

+59
-16
lines changed

src/libraries/Microsoft.Extensions.Http/src/Logging/HttpHeadersLogValue.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public KeyValuePair<string, object> this[int index]
6464
{
6565
if (index < 0 || index >= Count)
6666
{
67-
throw new IndexOutOfRangeException(nameof(index));
67+
throw new IndexOutOfRangeException();
6868
}
6969

7070
return Values[index];

src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ private void GenStruct(LoggerMethod lm, string nestedIndentation)
196196
");
197197
GenCases(lm, nestedIndentation);
198198
_builder.Append($@"
199-
{nestedIndentation}_ => throw new global::System.IndexOutOfRangeException(nameof(index)), // return the same exception LoggerMessage.Define returns in this case
199+
{nestedIndentation}_ => throw new global::System.IndexOutOfRangeException(), // return the same exception LoggerMessage.Define returns in this case
200200
{nestedIndentation}}};
201201
}}
202202

src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public FormattedLogValues(string? format, params object?[]? values)
6666
{
6767
if (index < 0 || index >= Count)
6868
{
69-
throw new IndexOutOfRangeException(nameof(index));
69+
throw new IndexOutOfRangeException();
7070
}
7171

7272
if (index == Count - 1)

src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ internal string Format(object? arg0, object? arg1, object? arg2) =>
222222
{
223223
if (index < 0 || index > _valueNames.Count)
224224
{
225-
throw new IndexOutOfRangeException(nameof(index));
225+
throw new IndexOutOfRangeException();
226226
}
227227

228228
if (_valueNames.Count > index)

src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerMessage.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ public LogValues(LogValuesFormatter formatter)
482482
{
483483
return new KeyValuePair<string, object?>("{OriginalFormat}", _formatter.OriginalFormat);
484484
}
485-
throw new IndexOutOfRangeException(nameof(index));
485+
throw new IndexOutOfRangeException();
486486
}
487487
}
488488

@@ -525,7 +525,7 @@ public LogValues(LogValuesFormatter formatter, T0 value0)
525525
case 1:
526526
return new KeyValuePair<string, object?>("{OriginalFormat}", _formatter.OriginalFormat);
527527
default:
528-
throw new IndexOutOfRangeException(nameof(index));
528+
throw new IndexOutOfRangeException();
529529
}
530530
}
531531
}
@@ -577,7 +577,7 @@ public LogValues(LogValuesFormatter formatter, T0 value0, T1 value1)
577577
case 2:
578578
return new KeyValuePair<string, object?>("{OriginalFormat}", _formatter.OriginalFormat);
579579
default:
580-
throw new IndexOutOfRangeException(nameof(index));
580+
throw new IndexOutOfRangeException();
581581
}
582582
}
583583
}
@@ -626,7 +626,7 @@ IEnumerator IEnumerable.GetEnumerator()
626626
case 3:
627627
return new KeyValuePair<string, object?>("{OriginalFormat}", _formatter.OriginalFormat);
628628
default:
629-
throw new IndexOutOfRangeException(nameof(index));
629+
throw new IndexOutOfRangeException();
630630
}
631631
}
632632
}
@@ -684,7 +684,7 @@ IEnumerator IEnumerable.GetEnumerator()
684684
case 4:
685685
return new KeyValuePair<string, object?>("{OriginalFormat}", _formatter.OriginalFormat);
686686
default:
687-
throw new IndexOutOfRangeException(nameof(index));
687+
throw new IndexOutOfRangeException();
688688
}
689689
}
690690
}
@@ -748,7 +748,7 @@ IEnumerator IEnumerable.GetEnumerator()
748748
case 5:
749749
return new KeyValuePair<string, object?>("{OriginalFormat}", _formatter.OriginalFormat);
750750
default:
751-
throw new IndexOutOfRangeException(nameof(index));
751+
throw new IndexOutOfRangeException();
752752
}
753753
}
754754
}
@@ -816,7 +816,7 @@ IEnumerator IEnumerable.GetEnumerator()
816816
case 6:
817817
return new KeyValuePair<string, object?>("{OriginalFormat}", _formatter.OriginalFormat);
818818
default:
819-
throw new IndexOutOfRangeException(nameof(index));
819+
throw new IndexOutOfRangeException();
820820
}
821821
}
822822
}

src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
2727
{
2828
0 => new global::System.Collections.Generic.KeyValuePair<string, object?>("{OriginalFormat}", ""),
2929

30-
_ => throw new global::System.IndexOutOfRangeException(nameof(index)), // return the same exception LoggerMessage.Define returns in this case
30+
_ => throw new global::System.IndexOutOfRangeException(), // return the same exception LoggerMessage.Define returns in this case
3131
};
3232
}
3333

src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDynamicLogLevel.generated.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
2727
{
2828
0 => new global::System.Collections.Generic.KeyValuePair<string, object?>("{OriginalFormat}", "M9"),
2929

30-
_ => throw new global::System.IndexOutOfRangeException(nameof(index)), // return the same exception LoggerMessage.Define returns in this case
30+
_ => throw new global::System.IndexOutOfRangeException(), // return the same exception LoggerMessage.Define returns in this case
3131
};
3232
}
3333

src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithMoreThan6Params.generated.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
6060
6 => new global::System.Collections.Generic.KeyValuePair<string, object?>("p7", this._p7),
6161
7 => new global::System.Collections.Generic.KeyValuePair<string, object?>("{OriginalFormat}", "M9 {p1} {p2} {p3} {p4} {p5} {p6} {p7}"),
6262

63-
_ => throw new global::System.IndexOutOfRangeException(nameof(index)), // return the same exception LoggerMessage.Define returns in this case
63+
_ => throw new global::System.IndexOutOfRangeException(), // return the same exception LoggerMessage.Define returns in this case
6464
};
6565
}
6666

src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerExtensionsTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ public KeyValuePair<string, object> this[int index]
942942
{
943943
return new KeyValuePair<string, object>(nameof(Value), Value);
944944
}
945-
throw new IndexOutOfRangeException(nameof(index));
945+
throw new IndexOutOfRangeException();
946946
}
947947
}
948948

src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerMessageTest.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,5 +471,48 @@ private void AssertLogValues(
471471

472472
Assert.Equal(expected, actual);
473473
}
474+
475+
[Theory]
476+
[InlineData(0)]
477+
[InlineData(1)]
478+
[InlineData(2)]
479+
[InlineData(3)]
480+
[InlineData(4)]
481+
[InlineData(5)]
482+
[InlineData(6)]
483+
public void LogValues_OutOfRangeAccess_ThrowsIndexOutOfRangeExceptionWithDefaultMessage(int parameterCount)
484+
{
485+
// Arrange
486+
var testSink = new TestSink();
487+
var testLogger = new TestLogger("testlogger", testSink, enabled: true);
488+
489+
Delegate logAction = parameterCount switch
490+
{
491+
0 => LoggerMessage.Define(LogLevel.Information, new EventId(1), "Test"),
492+
1 => LoggerMessage.Define<string>(LogLevel.Information, new EventId(1), "Test {P0}"),
493+
2 => LoggerMessage.Define<string, string>(LogLevel.Information, new EventId(1), "Test {P0} {P1}"),
494+
3 => LoggerMessage.Define<string, string, string>(LogLevel.Information, new EventId(1), "Test {P0} {P1} {P2}"),
495+
4 => LoggerMessage.Define<string, string, string, string>(LogLevel.Information, new EventId(1), "Test {P0} {P1} {P2} {P3}"),
496+
5 => LoggerMessage.Define<string, string, string, string, string>(LogLevel.Information, new EventId(1), "Test {P0} {P1} {P2} {P3} {P4}"),
497+
6 => LoggerMessage.Define<string, string, string, string, string, string>(LogLevel.Information, new EventId(1), "Test {P0} {P1} {P2} {P3} {P4} {P5}"),
498+
_ => throw new ArgumentOutOfRangeException(nameof(parameterCount))
499+
};
500+
501+
var parameters = Enumerable.Repeat("test", parameterCount).ToArray();
502+
503+
// Act
504+
logAction.DynamicInvoke(new object[] { testLogger }.Concat(parameters).Append(null).ToArray());
505+
506+
// Assert
507+
Assert.Single(testSink.Writes);
508+
var write = testSink.Writes.First();
509+
var logValues = Assert.IsAssignableFrom<IReadOnlyList<KeyValuePair<string, object>>>(write.State);
510+
511+
var exception = Assert.Throws<IndexOutOfRangeException>(() => logValues[logValues.Count + 1]);
512+
513+
// Verify the exception message is not just "index" but has a proper default message
514+
Assert.NotEqual("index", exception.Message);
515+
Assert.False(string.IsNullOrEmpty(exception.Message));
516+
}
474517
}
475518
}

0 commit comments

Comments
 (0)