-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Get EmptyHttpResult in RDF via reflection #45878
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
Conversation
01e1a9c
to
9519064
Compare
// Due to https://github.com/dotnet/aspnetcore/issues/41330 we cannot reference the EmptyHttpResult type | ||
// but users still need to assert on it as in https://github.com/dotnet/aspnetcore/issues/45063 | ||
// so we temporarily work around this here by using reflection to get the actual type. | ||
private static readonly NewExpression EmptyHttpResultValueTaskExpr = Type.GetType("Microsoft.AspNetCore.Http.Results, Microsoft.AspNetCore.Http.Results") is {} resultsType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conditional primarily exists to support scenarios where RDF is instantiated in scenarios where the Results assembly isn't referenced (SignalR tests). This shouldn't impact scenarios where users are running this from the framework.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using Expression.New(typeof(ValueTask<object>))
which I think would result in a null
being serialized to the response, can we make this throw lazily if we ever actually try building an expression tree with this and we cannot find the resultsType
? Or maybe just continue using the private version of EmptyHttpResult?
I know this should only affect tests, but it's probably better to either make it throw or make it work to make debugging our tests easier in the future. I think throwing is probably the best option. We can add dependencies to any tests that need to use this NewExpression which will make them more real-world anyway.
@@ -2154,32 +2159,34 @@ static async Task ExecuteAwaited(ValueTask task) | |||
|
|||
private static ValueTask<object?> ExecuteTaskWithEmptyResult(Task task) | |||
{ | |||
Debug.Assert(EmptyHttpResultInstance is not null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is not possible to it be null
in the SignalR
scenario? Or, maybe the SignalR
scenario is edge case that should never happen in real world?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this would be null in our SignalR tests currently since they don't reference the Results assembly, but I don't think the signalr tests are hitting this code path.
That said, we run our tests in release on the CI, so it might be better to reference a property that's basically just => EmptyHttpResultInstance ?? throw new UnreachableException("The EmptyHttpResult type could not be found.")
. instead of using EmptyHttpResultInstance directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, the problem in the SignalR tests was the resolution that was happening for the assembly in the static properties. I cleaned this up to account for Stephen's feedback and reused the same EmptyHttpResult.Instance
variable when constructing the property.
// Due to https://github.com/dotnet/aspnetcore/issues/41330 we cannot reference the EmptyHttpResult type | ||
// but users still need to assert on it as in https://github.com/dotnet/aspnetcore/issues/45063 | ||
// so we temporarily work around this here by using reflection to get the actual type. | ||
private static readonly NewExpression EmptyHttpResultValueTaskExpr = Type.GetType("Microsoft.AspNetCore.Http.Results, Microsoft.AspNetCore.Http.Results") is {} resultsType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using Expression.New(typeof(ValueTask<object>))
which I think would result in a null
being serialized to the response, can we make this throw lazily if we ever actually try building an expression tree with this and we cannot find the resultsType
? Or maybe just continue using the private version of EmptyHttpResult?
I know this should only affect tests, but it's probably better to either make it throw or make it work to make debugging our tests easier in the future. I think throwing is probably the best option. We can add dependencies to any tests that need to use this NewExpression which will make them more real-world anyway.
@@ -2154,32 +2159,34 @@ static async Task ExecuteAwaited(ValueTask task) | |||
|
|||
private static ValueTask<object?> ExecuteTaskWithEmptyResult(Task task) | |||
{ | |||
Debug.Assert(EmptyHttpResultInstance is not null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this would be null in our SignalR tests currently since they don't reference the Results assembly, but I don't think the signalr tests are hitting this code path.
That said, we run our tests in release on the CI, so it might be better to reference a property that's basically just => EmptyHttpResultInstance ?? throw new UnreachableException("The EmptyHttpResult type could not be found.")
. instead of using EmptyHttpResultInstance directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would still prefer if this threw in release builds if EmptyHttpResultInstance
is null.
Ah, I misunderstood what you're previous feedback was. I thought you meant throw exceptions in all builds (which would impact our local test scenario). I can add an if-def to throw on RELEASE builds. |
/backport to release/7.0 |
Started backporting to release/7.0: https://github.com/dotnet/aspnetcore/actions/runs/3898500659 |
@captainsafia backporting to release/7.0 failed, the patch most likely resulted in conflicts: $ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Applying: Get EmptyHttpResult in RDF via reflection
Using index info to reconstruct a base tree...
M src/Http/Http.Extensions/src/RequestDelegateFactory.cs
M src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
Falling back to patching base and 3-way merge...
Auto-merging src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
CONFLICT (content): Merge conflict in src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
Auto-merging src/Http/Http.Extensions/src/RequestDelegateFactory.cs
CONFLICT (content): Merge conflict in src/Http/Http.Extensions/src/RequestDelegateFactory.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Get EmptyHttpResult in RDF via reflection
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128 Please backport manually! |
@captainsafia an error occurred while backporting to release/7.0, please check the run log for details! Error: git am failed, most likely due to a merge conflict. |
* Get EmptyHttpResult in RDF via reflection * Always use instance property for checks * Favor Debug.Assert instead of early exception * Throw exception in RELEASE builds * Fix ifdef
* Get EmptyHttpResult in RDF via reflection (#45878) * Get EmptyHttpResult in RDF via reflection * Always use instance property for checks * Favor Debug.Assert instead of early exception * Throw exception in RELEASE builds * Fix ifdef * Add HttpResults using
Addresses #45063