-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Forms PRG and error handling fixes #49472
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
…test scripts yet though)
MappingScopeName = mappingScopeName; | ||
RestrictToFormName = restrictToFormName; | ||
AcceptMappingScopeName = acceptMappingScopeName; | ||
AcceptFormName = acceptFormName; |
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.
These unrelated renames are follow-up on code-review feedback from an earlier PR. Just trying to clear up!
I don't think we should do streaming rendering before we dispatch the event. It will result in a very inconsistent experience if you try to alter the response in any way as part of the POST and there is not a ton of value for it. (You are not getting to the page for the first time nor getting new data to consume, you are waiting the results from an action you triggered). |
Great point. TBH I don't have a certain sense of there being important scenarios for streaming before dispatching the event, now you've made me think of it more clearly. Happy to leave it as-is then. |
Hello - Was the issue reported by Daniel in #49143 fixed in the latest release? I am still having that issue. Is there a workaround for this? The form code below crashes. Index Hello, world!Welcome to your new app. Submit and navigate@code { |
Hi @darena-pjindal. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
@darena-pjindal Are you sure that code crashes? It works fine for me. Is it possible that it doesn't really crash, but you've got the VS debugger connected and it's telling you about first-chance exceptions instead? |
Hi @SteveSandersonMS - |
Hi @darena-pjindal. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Yes, see the checkbox in the screenshot labelled "break when this exception type is user-unhandled" |
Ah ok. That made it work. Thank you so much. |
Hi @darena-pjindal. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Hi @SteveSandersonMS Long time! Hey, I'm also getting the NavigationException in VS Code, as part of a tutorial I'm preparing for folks new to Blazor: I don't think it is a good experience for folks new to the platform, and they should not need to mess around with code editor settings to work around such a simple scenario. Is there anything that can be done to properly handle the exception in the runtime itself? |
are you sure you are not mixing renderModes? i.e. you are trying to NavigateTo from a SSR mode page to an InteractiveServer one? |
I'm sure. There's no interactivity enabled for this project. Pure SSR. |
Got it, happens here: public void AddGameDetails()
{
DB.GameDetails.Add(GameDetails);
NavigationManager.NavigateTo("/gamedetails");
} But does not happen here: public async Task AddGameDetails()
{
DB.GameDetails.Add(GameDetails);
NavigationManager.NavigateTo("/gamedetails");
await Task.CompletedTask;
} Created that with the Blazor scaffolder in VS. In the async version I see this in the debugger logs: Exception thrown: 'Microsoft.AspNetCore.Components.NavigationException' in Microsoft.AspNetCore.Components.Endpoints.dll ...but the debugger does not break into the exception and the app happily continues to the next page. |
Hey @julioct!
I'm afraid the exception already is properly handled in the runtime itself. That's why the app "happily continues to the next page". The issue is just that the debugger is being very proactive about telling you about an internal implementation detail of the framework (this exception). People don't need to know about this, so it's unfortunate it shows up on the log there. Longer term we might change how the navigation is signalled to avoid this sort of weirdness. Nobody really likes using an exception here, but we did it to recreate the same semantics that happen on other platforms. We may decide that allowing the app code to continue executing even after the redirection is acceptable, and then would not need to use the exception. |
Sounds good, thank you Steve! |
Interestingly, if I wrap
in a try-catch block, the redirection does not happen (as it hits the catch block). Any insights on how I can get this to work in a try-catch block correctly? |
Don't catch |
@SteveSandersonMS I have a Login Form inside a Blazor Server App which is working fine with built-in functionality. I tried this in my Login Component
This login Component is in a Static Server Render mode whereas after the successful SignIn, the User will be redirected to an Interactive Server Component. But Navigation is not working and I am getting this exception
|
@mohiyo please don't comment on closed PRs. File a separate issue instead. What's likely happening is that you are breaking on first chance exceptions. NavigationException is thrown by the framework to trigger an SSR navigation, but it's caught internally. If you have a try..catch you should avoid capturing NavigationException. |
Fixes #47903 and #49143
Mostly it's just tweaks to the flow in
RazorComponentEndpointInvoker
, plus a ton of E2E cases.Forms + streaming rendering
While doing this I realised the way we dispatch form events isn't as integrated into streaming SSR as I thought. What I thought would happen is:
... but what actually happens is:
So, it's not streaming until the submit event is dispatched. I tried fixing this but it involves more changes than I was ready to do just hours before the CC deadline. One particularly tricky bit is that the handling for returning 400 errors in the case of invalid/missing form names relies on the response not yet having started. If we are willing to do real streaming before we even get to the submit event dispatch, we also have to deal with the case where we then see it's an invalid submission but the response has already started.
We already handle "error after response already started" when it's an exception - we send a message over the SSR channel about it. Extending this to handle cases that aren't unhandled exceptions makes the flow more complex.
If we choose to do this in the future, the main aspects of the work are something like:
DispatchEventAsync
insideBeginRenderingRootComponent
.BeginRenderingRootComponent
should continue waiting only until the non-streaming tasks have completed and then return anHtmlRootComponent
, but now it should represent the entire rest of the process including event dispatch. That way the upstream code doesn't have to differentiate all these cases.protected
API onStaticHtmlRenderer
that waits for a supplied task (for which we'll pass the original quiescence task) and then dispatches an event and return anHtmlRootComponent
with aQuiescenceTask
representing quiescence after that eventEndpointHtmlRenderer
would return that instead of the originalHtmlRootComponent
NavigationException
and convert that into a 400 (if the response hasn't started) or a new streaming SSR message (if it has)That's not going to happen for preview 7 but we can consider whether it's important for RC1.
Update Great point from @javiercn below about why the user experience is better if we don't change this: #49472 (comment)