Skip to content

Fix PersistentState to throw clear error message for non-public properties #63125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 5, 2025

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Aug 5, 2025

The PersistentState attribute was throwing a confusing error message when used with private properties, making it difficult for developers to understand and fix the issue.

Problem

When a developer annotated a private property with [PersistentState], the runtime error was:

Property currentCount not found on type BlazorApp.Net10.Components.Pages.Counter

This was misleading because the property DID exist - it just wasn't public. The error didn't provide any guidance on how to fix the issue.

Root Cause

The PropertyGetterFactory method in PersistentValueProviderComponentSubscription.cs used type.GetProperty(propertyName) which by default only searches for public properties. When a private property was found during component scanning but couldn't be accessed during runtime, it appeared as "not found."

Solution

Enhanced the property lookup and validation logic to provide a clear, unified error message for all cases where a public property with a public getter cannot be found.

Before/After

Before:

Property currentCount not found on type BlazorApp.Net10.Components.Pages.Counter

After:

A public property 'currentCount' on component type 'BlazorApp.Net10.Components.Pages.Counter' with a public getter wasn't found.

The new error message clearly explains what's expected and covers all failure scenarios:

  • Property doesn't exist at all
  • Property exists but isn't public
  • Property is public but getter isn't public

Testing

  • Added comprehensive tests covering private properties, private getters, and public properties
  • Verified all existing tests continue to pass
  • Ensured the fix follows clean error handling patterns

Fixes #62859.


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

@Copilot Copilot AI changed the title [WIP] PersistentState attribute throws InvalidOperationException at runtime when used with private property Fix PersistentState to throw clear error message for non-public properties Aug 5, 2025
@Copilot Copilot AI requested a review from javiercn August 5, 2025 08:01
Copilot finished work on behalf of javiercn August 5, 2025 08:01
@javiercn javiercn marked this pull request as ready for review August 5, 2025 09:23
@Copilot Copilot AI review requested due to automatic review settings August 5, 2025 09:23
@javiercn javiercn requested a review from a team as a code owner August 5, 2025 09:23
Copy link
Contributor

@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 improves error messaging for the PersistentState attribute when used with non-public properties. Previously, developers received a confusing "Property not found" error when applying [PersistentState] to private properties, even though the property existed. The fix provides clear, actionable error messages that explain the public visibility requirement.

  • Enhanced property lookup logic to detect non-public properties and provide specific error messages
  • Added comprehensive test coverage for private properties, private getters, and public properties
  • Maintained performance by checking public properties first before falling back to broader search

Reviewed Changes

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

File Description
src/Components/Components/src/PersistentState/PersistentValueProviderComponentSubscription.cs Enhanced property lookup and validation logic with better error messaging
src/Components/Components/test/PersistentValueProviderComponentSubscriptionTests.cs Added test coverage for private property scenarios and validation
Comments suppressed due to low confidence (1)

src/Components/Components/test/PersistentValueProviderComponentSubscriptionTests.cs:639

  • The opening curly brace should be on a new line according to the coding guidelines. It should be:
public string PropertyWithPrivateGetter 
{ 
    private get; set; 
} = "initial";
        public string PropertyWithPrivateGetter { private get; set; } = "initial";

@Copilot Copilot AI requested a review from javiercn August 5, 2025 09:24
Copilot finished work on behalf of javiercn August 5, 2025 09:24
Comment on lines 234 to 240
// Check if the property exists but is not public to provide a better error message
var nonPublicProperty = type.GetProperty(propertyName, ComponentProperties.BindablePropertyFlags);
if (nonPublicProperty != null)
{
throw new InvalidOperationException(
$"The property '{propertyName}' on component type '{type.FullName}' cannot be used with {nameof(PersistentStateAttribute)} because it is not public. Properties with {nameof(PersistentStateAttribute)} must have a public getter.");
}
Copy link
Member

Choose a reason for hiding this comment

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

Just combine all the checks into a single one with a single error message for all cases. A public property X on component type Y with a public getter wasn't found.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

@copilot address the remaining feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Combined all error checks into a single condition with the simplified error message as requested. The new message "A public property '{propertyName}' on component type '{type.FullName}' with a public getter wasn't found" covers all failure scenarios. Tests updated accordingly and pass. (commit edc2fcf)

@Copilot Copilot AI requested a review from javiercn August 5, 2025 11:05
Copilot finished work on behalf of javiercn August 5, 2025 11:05
@javiercn javiercn merged commit f9722e5 into main Aug 5, 2025
30 checks passed
@javiercn javiercn deleted the copilot/fix-62859 branch August 5, 2025 13:30
@dotnet-policy-service dotnet-policy-service bot added this to the 10.0-rc1 milestone Aug 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PersistentState attribute throws InvalidOperationException at runtime when used with private property
3 participants