Skip to content

fix: Add opt-in diagnostic logging for OData query validation failures - #1592

Merged
WanjohiSammy merged 5 commits into
mainfrom
fix/query-validation-error-logging
Jul 22, 2026
Merged

WanjohiSammy merged 5 commits into
mainfrom
fix/query-validation-error-logging

Conversation

@WanjohiSammy

Copy link
Copy Markdown
Member

Summary

When an OData request has a $select/$expand that queries a property that does not exist on the target type, the query parser throws while validating: the controller path (EnableQueryAttribute) returns HTTP 400 and the minimal API path surfaces the ODataException from ODataQueryEndpointFilter. The parse throws before the parsed query options are populated, so telemetry that reads them sees an empty set and the failure gives no hint of the offending property, type, options, or endpoint.

This PR adds an opt-in structured ILogger diagnostic on the failure path (shared by both paths) that captures those details from request state that is still available. It is off by default; the HTTP response, its body, and the thrown exception are never changed.

Configuration (default is a no-op)

Off by default (EnableQueryValidationErrorLogging = false).

Setting Controller Minimal API
Enable per action/endpoint [EnableQuery(EnableQueryValidationErrorLogging = true)] .WithODataOptions(o => o.SetQueryValidationErrorLogging(true))
Enable globally ODataOptions.EnableQueryValidationErrorLogging = true services.AddOData(o => o.SetQueryValidationErrorLogging(true))
Level (global, default Warning) ODataOptions.QueryValidationErrorLogLevel = ... services.AddOData(o => o.SetQueryValidationErrorLogLevel(...))

After - opt-in

Example (console renderer, default level):

warn: Microsoft.AspNetCore.OData.Query.EnableQueryAttribute[0]
      OData query validation failed. Endpoint: odata/Customers, Type: NS.Customer, Query options: $expand=NoSuchOrders. Could not find a property named 'NoSuchOrders' on type 'NS.Customer'.
      Microsoft.OData.ODataException: Could not find a property named 'NoSuchOrders' on type 'NS.Customer'.

@WanjohiSammy

Copy link
Copy Markdown
Member Author

/AzurePipelines run

@azure-pipelines

Copy link
Copy Markdown
No pipelines are associated with this pull request.

@WanjohiSammy

Copy link
Copy Markdown
Member Author

/AzurePipelines run

@azure-pipelines

Copy link
Copy Markdown
No pipelines are associated with this pull request.

@WanjohiSammy

Copy link
Copy Markdown
Member Author

/AzurePipelines run

@azure-pipelines

Copy link
Copy Markdown
No pipelines are associated with this pull request.

@WanjohiSammy

Copy link
Copy Markdown
Member Author

/AzurePipelines run

@azure-pipelines

Copy link
Copy Markdown
No pipelines are associated with this pull request.

@WanjohiSammy

Copy link
Copy Markdown
Member Author

/AzurePipelines run

@azure-pipelines

Copy link
Copy Markdown
No pipelines are associated with this pull request.

@WanjohiSammy WanjohiSammy changed the title Add opt-in diagnostic logging for OData query validation failures fix: Add opt-in diagnostic logging for OData query validation failures Jul 20, 2026
@xuzhg
xuzhg requested a review from Copilot July 20, 2026 16:16
xuzhg
xuzhg previously approved these changes Jul 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 introduces opt-in structured diagnostic logging for OData query validation failures (notably invalid $select/$expand property access) and unifies the logging behavior across both controller-based (EnableQueryAttribute) and minimal API (ODataQueryEndpointFilter) pipelines, without changing HTTP responses or thrown exceptions.

Changes:

  • Added QueryValidationErrorLogger and integrated it into both EnableQueryAttribute and ODataQueryEndpointFilter failure paths behind opt-in configuration.
  • Introduced new configuration knobs for enabling the diagnostic and selecting its LogLevel (ODataOptions for controllers, ODataMiniOptions for minimal APIs), plus public API surface updates.
  • Added unit + E2E coverage (including “logger throws” safety cases) and fixed an async test deadlock risk by removing .Result.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/Microsoft.AspNetCore.OData.Tests/Query/EnableQueryAttributeTests.cs Adds unit coverage for opt-in logging behavior, global vs per-attribute precedence, and safety when logging is unavailable/throws.
test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.bsl Updates public API baseline for newly exposed options.
test/Microsoft.AspNetCore.OData.Tests/Batch/DefaultODataBatchHandlerTest.cs Replaces blocking .Result with await in an async test.
test/Microsoft.AspNetCore.OData.TestCommon/ThrowingLoggerProvider.cs Adds a test logger provider that throws to validate “logging must not affect outcome” behavior.
test/Microsoft.AspNetCore.OData.TestCommon/CapturingLoggerProvider.cs Adds a capturing provider to assert on structured logging fields in tests.
test/Microsoft.AspNetCore.OData.E2E.Tests/Query/QueryValidationErrorLogging/*.cs Adds controller-pipeline E2E coverage for enabled/disabled/global/custom-level scenarios.
test/Microsoft.AspNetCore.OData.E2E.Tests/MinimalApis/*.cs Adds minimal API E2E coverage for enabled/disabled/global/global-level and logger-failure scenarios.
src/Microsoft.AspNetCore.OData/Query/QueryValidationErrorLogger.cs New shared structured logging helper for query validation failures.
src/Microsoft.AspNetCore.OData/Query/ODataQueryEndpointFilter.cs Wraps validation to log (opt-in) on failure while preserving thrown exception behavior.
src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.cs Logs (opt-in) when producing bad request results from validation failures; captures processed options for post-action validation path.
src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.Config.cs Adds EnableQueryValidationErrorLogging attribute property with tri-state backing behavior.
src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt Declares new public API members for the added options.
src/Microsoft.AspNetCore.OData/ODataOptions.cs Adds global controller-pipeline configuration for enable + log level.
src/Microsoft.AspNetCore.OData/ODataMiniOptions.cs Adds minimal API configuration for enable + log level and merges into UpdateFrom.
src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml Updates XML docs to reflect new APIs and methods.

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

Comment thread src/Microsoft.AspNetCore.OData/Query/QueryValidationErrorLogger.cs Outdated
Comment thread src/Microsoft.AspNetCore.OData/Query/QueryValidationErrorLogger.cs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.

@WanjohiSammy
WanjohiSammy force-pushed the fix/query-validation-error-logging branch from 7a044a3 to 2bb5e33 Compare July 21, 2026 17:52
@WanjohiSammy

Copy link
Copy Markdown
Member Author

/AzurePipelines run

@azure-pipelines

Copy link
Copy Markdown
No pipelines are associated with this pull request.

WanjohiSammy and others added 4 commits July 22, 2026 10:02
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 07e2efd6-30b9-4867-9de3-44a8c60512b8
SendAsync_Works_ForBatchRequestWithInsertedEntityReferencedInAnotherRequest
blocked on client.SendAsync(...).Result inside an async xUnit test. Under
xUnit's AsyncTestSyncContext this can deadlock when a continuation resumes on
the captured context, causing the ~3m47s CI hang that surfaced as
TaskCanceledException. Await the call like every other request in the file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 93c49a7f-9734-49c7-ba83-073262b9b7f4
@WanjohiSammy
WanjohiSammy force-pushed the fix/query-validation-error-logging branch from 2bb5e33 to 23886d9 Compare July 22, 2026 07:03
// validation settings
private ODataValidationSettings _validationSettings;
private string _allowedOrderByProperties;
private bool? _enableQueryValidationErrorLogging;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can we use the ILogger directly?
I mean can we not use this configuration, instead, can we rely on customer's setting about the ILogger?
Fetch the certain 'ILogger' , if set, use it, otherwise, not log the error?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@copilot

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Using ILogger directly is possible, but I kept the explicit opt-in to avoid introducing new validation-failure logs for existing apps by default. Without the opt-in, any app with this category enabled would start getting warnings. If you prefer always-on behavior gated only by ILogger/category levels, I can update this PR to remove the opt-in switches.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I replied in-thread above with the tradeoff and can switch this PR to always-on ILogger-gated logging if you want that direction.

Copilot finished work on behalf of xuzhg July 22, 2026 16:45
Copilot AI requested a review from xuzhg July 22, 2026 16:45
@WanjohiSammy
WanjohiSammy merged commit c852dbe into main Jul 22, 2026
2 checks passed
@WanjohiSammy
WanjohiSammy deleted the fix/query-validation-error-logging branch July 22, 2026 17:34
WanjohiSammy added a commit that referenced this pull request Jul 27, 2026
… failures (#1597)

* Backports #1592 (commit c852dbe) from main to dev-10.x
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.

4 participants