Skip to content

Error page can't handle POST errors #18186

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

Closed
gbbsoft opened this issue Jan 8, 2020 · 24 comments
Closed

Error page can't handle POST errors #18186

gbbsoft opened this issue Jan 8, 2020 · 24 comments
Labels
affected-very-few This issue impacts very few customers area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates bug This issue describes a behavior which is not expected - a bug. Needs: Design This issue requires design work before implementating. reevaluate We need to reevaluate the issue and make a decision about it severity-nice-to-have This label is used by an internal tool
Milestone

Comments

@gbbsoft
Copy link

gbbsoft commented Jan 8, 2020

I think there is a bug in ExceptionHandlerMiddleware.cs.
if exception is throw during "POST" then Exception Handler call ExceptionHandlingPath also using "POST". I think it should call ExceptionHandlingPath using "GET", so please add ClearHttpContext following line:

context.Request.Method = "GET";

@analogrelay
Copy link
Contributor

This seems somewhat reasonable. It would be breaking to existing users though so we'll have to introduce it as a new option.

@analogrelay analogrelay added this to the Backlog milestone Jan 8, 2020
@analogrelay analogrelay added 5.0-candidate good first issue Good for newcomers. help wanted Up for grabs. We would accept a PR to help resolve this issue labels Jan 8, 2020
@analogrelay
Copy link
Contributor

We would review a PR contributing this fix if you're interested @gbbsoft .

@analogrelay
Copy link
Contributor

One thing that does come to mind though is that since this would have to be an opt-in feature, it might not solve the problem most users would have with this behavior. If the original problem is that the exception page logic is matching against Method and not expecting POST then a simple fix is to change the logic to allow POSTs. If we add this functionality, it would also require the user to understand this problem and change their app, so I'm not sure exactly what the value here is.

@gbbsoft
Copy link
Author

gbbsoft commented Jan 8, 2020

More interesting is when exception is in "DELETE" or "UPDATE"... :-)

@rynowak
Copy link
Member

rynowak commented Jan 9, 2020

One thing that does come to mind though is that since this would have to be an opt-in feature, it might not solve the problem most users would have with this behavior.

Why does it have to be opt-in? We wouldn't add a new option in a patch, so it would be in 5.0 which is a major.

Playing devils advocate a bit - this might have been the first time we've heard this complaint. Are more people depending on the current behavior?

@analogrelay
Copy link
Contributor

@rynowak Sure, we could also just take the break.

@gbbsoft
Copy link
Author

gbbsoft commented Jan 9, 2020

We would review a PR contributing this fix if you're interested @gbbsoft .

What does it mean?

@analogrelay
Copy link
Contributor

@gbbsoft I was suggesting that if you wanted to contribute this fix yourself, we'd be happy to review a Pull Request. If not, that's fine, it's on our queue and we'll look at it for a future release.

@Tratcher
Copy link
Member

Tratcher commented Jan 16, 2020

FYI this has come up at least once before and we declined to change it. #3555. I don't recommend taking this change now.

We want to preserve as much information as possible so the error page can accurately report what the original request was trying to do. Note we preserve the request body, method, query, headers, etc.. Changing only some of them would put the request in an inconsistent state (e.g. a GET request with a Content-Length header, a body, query parameters for some other page, etc..) and the results will be unpredictable.

Changing the path is necessary for re-routing the requests. The original path is preserved in a request feature: https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerFeature.cs.

The alternative is trying to capture the complete state of the original request and creating a completely new request structure for the exception handling. That's expensive, error prone, breaks extensibility, and fragile to maintain.

@Tratcher
Copy link
Member

More interesting is when exception is in "DELETE" or "UPDATE"... :-)

This does mean your exception handling endpoint needs to be capable of handling a wide variety of request. DELETE and UPDATE don't worry me, you control that endpoint, you control the behavior of any methods applied there.

@gbbsoft
Copy link
Author

gbbsoft commented Jan 16, 2020

@Tratcher So you can add option in ExceptionHandlerOptions: "bool ForceGET" (or similar) with default to false. This will not break any existing code.

And add in ExceptionHandlerFeature variable to remember original operation.

@Tratcher
Copy link
Member

That doesn't address the issue of the request being in an inconsistent state.

@vaughanr
Copy link
Contributor

@Tratcher your explanation makes sense to me. I did the pr just because it was marked as a good first issue. I'm happy to withdraw it myself and find a better one.

@Tratcher
Copy link
Member

Thanks @vaughanr. At the very least this needs more design before we can proceed to a PR.

@Tratcher Tratcher added Needs: Design This issue requires design work before implementating. and removed good first issue Good for newcomers. help wanted Up for grabs. We would accept a PR to help resolve this issue labels Jan 16, 2020
@gbbsoft
Copy link
Author

gbbsoft commented Jan 16, 2020

My main issue was: when exception had been during "POST" my error page was not called at all.

@Tratcher
Copy link
Member

@gbbsoft right. That can be addressed in routing like in #3555. How is the route set up for your error page?

@gbbsoft
Copy link
Author

gbbsoft commented Jan 16, 2020

My application is more complicate, because I have isolated multi-instance of my application, so path is https://gbbdance.gbbsoft.pl/eM_Studio/ where "eM_Studio" is an instance name. Than I created special ExceptionHandlerMiddleware to pass instance name to /Error, because there is no official way to create Path to Error dynamical.

Except it my Config() is "normal":

            app.UseMiddleware<GbbDance.Lib.ExceptionHandlerMiddleware>(new object[1]
                {
                    Microsoft.Extensions.Options.Options.Create(new ExceptionHandlerOptions
                        {
                            ExceptionHandlingPath = new PathString("/Error")
                        })
                });

And /Error was from template with small modifications:

             [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
             [AllowAnonymous]
             public class ErrorModel : PageModel
                {
                    private readonly Data.ApplicationDbContext DB;
                    public ErrorModel(Data.ApplicationDbContext db)
                    {
                        DB = db;
                    }
                    public string RequestId { get; set; }
                    public string Message { get; set; }
                    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
                    public void OnGet()
                    {
                        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
                        var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
                        if (exceptionHandlerPathFeature != null)
                        {
                             // get message from exception, sometimes convert it, and save it in DB
                            Message = DB.OurGetExceptionMessageUI(exceptionHandlerPathFeature.Error, exceptionHandlerPathFeature.Path, Request.QueryString.ToString());
                        }
                    }
                }

Later I had to add:

    // 2019-09-19: called then error on any "OnPost" procedures.
    public void OnPost()
    {
        OnGet();
    }

Later I rewrote ExceptionHandlerMiddleware to better process exceptions in OnPosts.

@Tratcher
Copy link
Member

So the only part you needed to workaround the title issue is this?

    public void OnPost()
    {
        OnGet();
    }

@pranavkm is there a way to make a razor page handle any method? We should update our error page.

@NTaylorMullen said this would work on a normal controller, so our other template is probably not affected.

@gbbsoft
Copy link
Author

gbbsoft commented Jan 16, 2020

Looking at this today: Yes. The simple (but I don't know if the best) is add OnPost with redirection to OnGet in /Error

The idea to correct template is very good! I spend some hours to find out why /Error is not called during OnPost.

@Tratcher Tratcher added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Jan 16, 2020
@Tratcher Tratcher changed the title Bug in ExceptionHandlerMiddleware.cs Error page can't handle POST errors Jan 16, 2020
@Tratcher Tratcher removed area-middleware Needs: Design This issue requires design work before implementating. labels Jan 16, 2020
@mkArtakMSFT mkArtakMSFT added this to the Next sprint planning milestone Jan 17, 2020
@mkArtakMSFT mkArtakMSFT added the bug This issue describes a behavior which is not expected - a bug. label Jan 17, 2020
@pranavkm
Copy link
Contributor

@pranavkm is there a way to make a razor page handle any method? We should update our error page.

The Page will still execute if no handler matches. A fairly trivial way to fix this would be to lazily evaluate RequestId:

public string RequestId => Activity.Current?.Id ?? HttpContext.TraceIdentifier;

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

private readonly ILogger<ErrorModel> _logger;

public ErrorModel(ILogger<ErrorModel> logger)
{
    _logger = logger;
}

@mkArtakMSFT
Copy link
Contributor

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@javiercn javiercn added affected-very-few This issue impacts very few customers severity-nice-to-have This label is used by an internal tool and removed 5.0-candidate labels Oct 9, 2020
@javiercn javiercn added the reevaluate We need to reevaluate the issue and make a decision about it label Apr 18, 2021
@rafikiassumani-msft rafikiassumani-msft added old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels Needs: Design This issue requires design work before implementating. and removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels Oct 20, 2021
@halter73
Copy link
Member

If we change the behavior here, we should add the original verb to the IExceptionHandlerPathFeature.

@ghost
Copy link

ghost commented Oct 11, 2022

Thanks for contacting us.

We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@captainsafia captainsafia added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels labels Jun 20, 2023
@captainsafia captainsafia modified the milestones: .NET 8 Planning, Backlog Mar 1, 2024
@mikekistler
Copy link
Contributor

This issue has been quiet for several years now. Many users have posted that the workaround described above works in their apps, so I'm going to close this as resolved. But if you are still encountering this issue and can't use the workaround given please add a new reply and re-open the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affected-very-few This issue impacts very few customers area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates bug This issue describes a behavior which is not expected - a bug. Needs: Design This issue requires design work before implementating. reevaluate We need to reevaluate the issue and make a decision about it severity-nice-to-have This label is used by an internal tool
Projects
No open projects
Status: No status
Development

No branches or pull requests