Skip to content

Add test project and improve logging error handling#2

Merged
olivegamestudio merged 3 commits intomainfrom
1-logging-crashes-at-runtime-due-to-mismatched-message-templates-and-arguments
Dec 15, 2025
Merged

Add test project and improve logging error handling#2
olivegamestudio merged 3 commits intomainfrom
1-logging-crashes-at-runtime-due-to-mismatched-message-templates-and-arguments

Conversation

@olivegamestudio
Copy link
Owner

  • Move main project to src/ and add tests/FluentLoggerExtensions.Tests
  • Wrap CallerLogContextExtensions logging calls in try-catch to log errors on template/argument mismatch
  • Add xUnit/Moq tests for all logging methods to verify robustness
  • Add LoggerMoqExtensions helper for verifying log output in tests

- Move main project to src/ and add tests/FluentLoggerExtensions.Tests
- Wrap CallerLogContextExtensions logging calls in try-catch to log errors on template/argument mismatch
- Add xUnit/Moq tests for all logging methods to verify robustness
- Add LoggerMoqExtensions helper for verifying log output in tests
Copilot AI review requested due to automatic review settings December 15, 2025 16:40
@olivegamestudio olivegamestudio merged commit 95f599d into main Dec 15, 2025
1 check passed
@olivegamestudio olivegamestudio deleted the 1-logging-crashes-at-runtime-due-to-mismatched-message-templates-and-arguments branch December 15, 2025 16:49
Copy link

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 pull request restructures the project by moving the main library to a src/ directory and introduces a comprehensive test suite with error handling improvements. The primary goal is to improve the robustness of the logging extensions by wrapping logging calls in try-catch blocks to handle template/argument mismatches gracefully, while adding extensive tests to verify this behavior.

Key Changes:

  • Added try-catch error handling to all logging methods (LogInformation, LogError, LogDebug, LogWarning) to prevent exceptions from template/argument mismatches
  • Created a new test project with xUnit/Moq tests covering all logging scenarios including edge cases
  • Reorganized project structure by moving source code to src/ directory

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/FluentLoggerExtensions.Tests/FluentLoggerExtensions.Tests.csproj New test project configuration with xUnit, Moq, and test SDK dependencies
tests/FluentLoggerExtensions.Tests/LoggerMoqExtensions.cs Helper extension for verifying log output in tests using Moq
tests/FluentLoggerExtensions.Tests/CallerLogContextLogInformationTests.cs Test suite for LogInformation method covering various scenarios
tests/FluentLoggerExtensions.Tests/CallerLogContextLogWarningTests.cs Test suite for LogWarning method covering various scenarios
tests/FluentLoggerExtensions.Tests/CallerLogContextLogErrorTests.cs Test suite for LogError method covering various scenarios
tests/FluentLoggerExtensions.Tests/CallerLogContextLogDebugTests.cs Test suite for LogDebug method covering various scenarios
src/CallerLogContextExtensions.cs Added try-catch error handling to all logging methods with fallback error logging
src/FluentLoggerExtensions.cs New file containing the WithCaller extension method (moved from original location)
src/CallerLogContext.cs New file defining the CallerLogContext struct (moved from original location)
src/FluentLoggerExtensions.csproj Updated project file to include README in NuGet package
FluentLoggerExtensions.slnx Updated solution file to reference reorganized projects
.github/workflows/dotnet-desktop.yml Added test execution step and automated version tagging
Comments suppressed due to low confidence (5)

src/CallerLogContextExtensions.cs:18

  • The variable 'fileName' is declared as non-nullable (string), but context.File is nullable (string?). If context.File is null, Path.GetFileName will return an empty string, which is then assigned to a non-nullable variable. Consider either declaring fileName as string? or using the null-forgiving operator (!) if null is not expected.
    src/CallerLogContextExtensions.cs:44
  • The variable 'fileName' is declared as non-nullable (string), but context.File is nullable (string?). If context.File is null, Path.GetFileName will return an empty string, which is then assigned to a non-nullable variable. Consider either declaring fileName as string? or using the null-forgiving operator (!) if null is not expected.
    src/CallerLogContextExtensions.cs:70
  • The variable 'fileName' is declared as non-nullable (string), but context.File is nullable (string?). If context.File is null, Path.GetFileName will return an empty string, which is then assigned to a non-nullable variable. Consider either declaring fileName as string? or using the null-forgiving operator (!) if null is not expected.
    src/CallerLogContextExtensions.cs:96
  • The variable 'fileName' is declared as non-nullable (string), but context.File is nullable (string?). If context.File is null, Path.GetFileName will return an empty string, which is then assigned to a non-nullable variable. Consider either declaring fileName as string? or using the null-forgiving operator (!) if null is not expected.
    src/CallerLogContextExtensions.cs:84
  • Using LogDebug in the error handler for a failed LogDebug call is problematic. If the logger is misconfigured or has issues, this could silently swallow the error since debug logs are often disabled in production. Consider using LogError or LogWarning for the fallback logging to ensure the failure is visible.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
Times.Once);
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The 'times' parameter is declared but never used in the method. It should either be removed if not needed, or passed to the Verify call. Currently, the verification always uses Times.Once regardless of the 'times' parameter value.

Suggested change
Times.Once);
times ?? Times.Once);

Copilot uses AI. Check for mistakes.
[Theory]
[InlineData("This is a test log message")]
[InlineData("This is another test log message")]
[InlineData("This is a really log test message")]
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test description "This is a really log test message" contains a grammatical error. It should be "This is a really long test message" (with "long" instead of "log").

Suggested change
[InlineData("This is a really log test message")]
[InlineData("This is a really long test message")]

Copilot uses AI. Check for mistakes.
}

[Fact]
public void Mismatched_placeholders_throw_when_state_is_enumerated()
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test method name uses snake_case naming convention ("Mismatched_placeholders_throw_when_state_is_enumerated"), which is inconsistent with the PascalCase naming used in other test methods in this file (e.g., "LogWarning_WithPlainMessage_DoesNotThrow"). Consider renaming to "MismatchedPlaceholders_ThrowWhenStateIsEnumerated" for consistency.

Suggested change
public void Mismatched_placeholders_throw_when_state_is_enumerated()
public void MismatchedPlaceholders_ThrowWhenStateIsEnumerated()

Copilot uses AI. Check for mistakes.
[Theory]
[InlineData("This is a test log message")]
[InlineData("This is another test log message")]
[InlineData("This is a really log test message")]
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test description "This is a really log test message" contains a grammatical error. It should be "This is a really long test message" (with "long" instead of "log").

Suggested change
[InlineData("This is a really log test message")]
[InlineData("This is a really long test message")]

Copilot uses AI. Check for mistakes.
}

[Fact]
public void Mismatched_placeholders_throw_when_state_is_enumerated()
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test method name uses snake_case naming convention ("Mismatched_placeholders_throw_when_state_is_enumerated"), which is inconsistent with the PascalCase naming used in other test methods in this file (e.g., "LogInformation_WithPlainMessage_DoesNotThrow"). Consider renaming to "MismatchedPlaceholders_ThrowWhenStateIsEnumerated" for consistency.

Suggested change
public void Mismatched_placeholders_throw_when_state_is_enumerated()
public void MismatchedPlaceholders_ThrowWhenStateIsEnumerated()

Copilot uses AI. Check for mistakes.
[Theory]
[InlineData("This is a test log message")]
[InlineData("This is another test log message")]
[InlineData("This is a really log test message")]
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test description "This is a really log test message" contains a grammatical error. It should be "This is a really long test message" (with "long" instead of "log").

Suggested change
[InlineData("This is a really log test message")]
[InlineData("This is a really long test message")]

Copilot uses AI. Check for mistakes.
}

[Fact]
public void Mismatched_placeholders_throw_when_state_is_enumerated()
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test method name uses snake_case naming convention ("Mismatched_placeholders_throw_when_state_is_enumerated"), which is inconsistent with the PascalCase naming used in other test methods in this file (e.g., "LogError_WithPlainMessage_DoesNotThrow"). Consider renaming to "MismatchedPlaceholders_ThrowWhenStateIsEnumerated" for consistency.

Suggested change
public void Mismatched_placeholders_throw_when_state_is_enumerated()
public void MismatchedPlaceholders_ThrowWhenStateIsEnumerated()

Copilot uses AI. Check for mistakes.
}

[Fact]
public void Mismatched_placeholders_throw_when_state_is_enumerated()
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test method name uses snake_case naming convention ("Mismatched_placeholders_throw_when_state_is_enumerated"), which is inconsistent with the PascalCase naming used in other test methods in this file (e.g., "LogDebug_WithPlainMessage_DoesNotThrow"). Consider renaming to "MismatchedPlaceholders_ThrowWhenStateIsEnumerated" for consistency.

Suggested change
public void Mismatched_placeholders_throw_when_state_is_enumerated()
public void MismatchedPlaceholders_ThrowWhenStateIsEnumerated()

Copilot uses AI. Check for mistakes.
[Theory]
[InlineData("This is a test log message")]
[InlineData("This is another test log message")]
[InlineData("This is a really log test message")]
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The test description "This is a really log test message" contains a grammatical error. It should be "This is a really long test message" (with "long" instead of "log").

Suggested change
[InlineData("This is a really log test message")]
[InlineData("This is a really long test message")]

Copilot uses AI. Check for mistakes.
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.

Logging crashes at runtime due to mismatched message templates and arguments

2 participants