Hi team, in my DotVVM project I have a global DotVVM.Framework.Runtime.Filters.ExceptionFilterAttribute class. The OnPageExceptionAsync is being called whenever I call Context.ReturnFileAsync within the page ViewModel staticcommand (to send back a handy CSV file from the grid on the screen). The user actually sees no error on the screen, and the file downloads, however page errors are being recorded as throwing System.InvalidOperationException each time this function is run.
Is there something I should do to fix or work around this? Any middleware ordering I should be careful of?
Versions: DotVVM 4.3.3, NET 8.0.11
Exception Detail:
System.InvalidOperationException: Headers are read-only, response has already started. at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.ThrowHeadersReadOnlyException() at DotVVM.Framework.Runtime.DefaultOutputRenderer.WriteViewModelResponse(IDotvvmRequestContext context, DotvvmView view) at DotVVM.Framework.Hosting.DotvvmPresenter.ProcessRequestCore(IDotvvmRequestContext context) in /_/src/Framework/Framework/Hosting/DotvvmPresenter.cs:line 290
Is there also a DotVVM.Framework.Hosting.DotvvmInterruptRequestExecutionException thrown? If yes, it is inevitable (by design) when calling Context.ReturnFileAsync(). We log it as a special case.
We identify it and log it in both OnCommandExceptionAsync() and OnPageExceptionAsync(). And we set context.IsCommandExceptionHandled and context.IsPageExceptionHandled accordingly.
Hi Marian, when the override OnPageExceptionAsync handler catches the Exception, context.IsPageExceptionHandled is false still, and DotvvmInterruptRequestExecutionException is not being caught here. I am not sure how I should manually ignore this exception in my handler code? Should I just look for the exception type being InvalidOperationException and ignore all of those? That seems dangerous… thanks
If no DotVVM.Framework.Hosting.DotvvmInterruptRequestExecutionException is thrown, then I don’t know how to help your situation and the DotVVM team would be more knowledgeable about this.
PS:
I’m using app.UseDotVVM<DotvvmStartup>() right before app.Run() in my .NET 8 Program.cs file.
PS 2:
I see now that I’m using Context.ReturnFileAsync() in a public async Task method that I bind in markup as a command and not as a staticCommand. Maybe this is your issue.
Hi! I don’t think this exception will inevitably occur, and I think there must be something catching the initial DotvvmInterruptRequestException for this to happen. I was unable to reproduce it with a simple staticCommand which returns a file, but I get this exact result if I catch the exception or suppress it in another filter’s OnCommandExceptionAsync.
Would you be able to debug step-by-step what happens after the DotvvmInterruptRequestExecutionException is thrown? It might not be “your fault”, given how simple is the scenario, I’d not be surprised if we accidentally consumed this exception somewhere in dotvvm framework.