Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jul 3, 2025

The enrichers were causing KeyNotFoundException when trying to access keys that don't exist in httpContext.Items. This was particularly problematic in Blazor server-side circuits where the HttpContext lifecycle differs from traditional HTTP requests.

Root Cause

The code was using direct dictionary access which throws exceptions for missing keys:

if (httpContext.Items[key] is LogEventProperty logEventProperty)

Solution

Replaced direct dictionary access with safe TryGetValue() calls:

if (httpContext.Items.TryGetValue(key, out var value) && value is LogEventProperty logEventProperty)

Files Fixed

  • ClientIpEnricher.cs - Fixed access to Serilog_ClientIp key
  • CorrelationIdEnricher.cs - Fixed access to Serilog_CorrelationId key
  • ClientHeaderEnricher.cs - Fixed access to header-specific keys

Testing

  • ✅ All 20 existing tests continue to pass
  • ✅ Added new test case for missing key scenarios
  • ✅ Manual testing confirms enrichers work correctly:
    • ClientIp extraction: 127.0.0.1
    • CorrelationId from headers: test-123
    • UserAgent extraction: TestAgent/1.0
  • ✅ No more KeyNotFoundException errors in any hosting scenario

This fix ensures the enrichers work reliably across all ASP.NET Core hosting models, including Blazor server-side circuits where this issue was most commonly reported.

Fixes #49.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 4 commits July 3, 2025 12:41
…bility

Co-authored-by: mo-esmp <1659032+mo-esmp@users.noreply.github.com>
…d of direct dictionary access

Co-authored-by: mo-esmp <1659032+mo-esmp@users.noreply.github.com>
Co-authored-by: mo-esmp <1659032+mo-esmp@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] System.Collections.Generic.KeyNotFoundException: 'The given key 'Serilog_ClientIp' was not present in the dictionary.' Fix KeyNotFoundException in enrichers when accessing httpContext.Items Jul 3, 2025
@Copilot Copilot AI requested a review from mo-esmp July 3, 2025 12:50
Copilot finished work on behalf of mo-esmp July 3, 2025 12:50
@mo-esmp mo-esmp marked this pull request as ready for review July 3, 2025 12:56
@Copilot Copilot AI review requested due to automatic review settings July 3, 2025 12:56
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR replaces direct httpContext.Items access with safe TryGetValue calls to prevent KeyNotFoundException in server-side Blazor and adds a test for the missing-IP scenario.

  • Switched to TryGetValue in three enrichers (ClientIp, CorrelationId, ClientHeader)
  • Added a new test for ClientIpEnricher when the key is absent
  • Verified no regressions and added broader hosting-model coverage

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/Serilog.Enrichers.ClientInfo.Tests/ClientIpEnricherTests.cs Added test for missing ClientIp key scenario
src/Serilog.Enrichers.ClientInfo/Enrichers/CorrelationIdEnricher.cs Switched to TryGetValue to safely read the item
src/Serilog.Enrichers.ClientInfo/Enrichers/ClientIpEnricher.cs Switched to TryGetValue to safely read the item
src/Serilog.Enrichers.ClientInfo/Enrichers/ClientHeaderEnricher.cs Switched to TryGetValue to safely read the item
Comments suppressed due to low confidence (2)

src/Serilog.Enrichers.ClientInfo/Enrichers/CorrelationIdEnricher.cs:47

  • Add a unit test for CorrelationIdEnricher to verify that it does not throw and correctly falls back when the CorrelationIdItemKey is missing from httpContext.Items.
        if (httpContext.Items.TryGetValue(CorrelationIdItemKey, out var value) && value is LogEventProperty logEventProperty)

src/Serilog.Enrichers.ClientInfo/Enrichers/ClientHeaderEnricher.cs:49

  • Add a unit test for ClientHeaderEnricher to ensure it handles a missing header item gracefully (no exception) and applies the correct fallback behavior.
        if (httpContext.Items.TryGetValue(_clientHeaderItemKey, out var value) && value is LogEventProperty logEventProperty)

@@ -38,7 +38,7 @@ public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)

var ipAddress = httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";

if (httpContext.Items[IpAddressItemKey] is LogEventProperty logEventProperty)
if (httpContext.Items.TryGetValue(IpAddressItemKey, out var value) && value is LogEventProperty logEventProperty)
Copy link
Preview

Copilot AI Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The TryGetValue+cast logic is duplicated across enrichers; consider extracting a shared helper or base-method to reduce duplication and improve maintainability.

Suggested change
if (httpContext.Items.TryGetValue(IpAddressItemKey, out var value) && value is LogEventProperty logEventProperty)
if (TryGetLogEventProperty(httpContext.Items, IpAddressItemKey, out var logEventProperty))

Copilot uses AI. Check for mistakes.

@mo-esmp mo-esmp merged commit 49ce1d7 into master Jul 19, 2025
1 check passed
@mo-esmp mo-esmp deleted the copilot/fix-49 branch July 19, 2025 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

System.Collections.Generic.KeyNotFoundException: 'The given key 'Serilog_ClientIp' was not present in the dictionary.'
2 participants