Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
215 views
in Technique[技术] by (71.8m points)

.net - How do I make a "generic error" page in my ASP.NET application so that it handles errors triggered when serving that page itself?

In my ASP.NET MVC application I want to have a generic error page that is showed together with returning HTTP 500. Something like this page on Stack Overflow.

Of course I'd like to reuse as much code as possible so that the page is styled the same way as other pages in my application, so I want to have an ASP.NET page reusing the master pages, not a plain HTML file. However if I do so I have a page that contains some server-side executable code for creating actual HTML served to the client. In case of Stack Overflow generic error page it's the code checking whether the user is registered, retrieving his rep, etc, and inserting elements for that into HTML.

That code can fail and if that happens the page isn't properly constructed and an exception is thrown in the server.

How do I handle that situation (error when building HTML for the error page) gracefully? What's the typical approach?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I like to start by categorize the possible errors.

Categorize the errors.

  1. Page Not Found (this is full my log).
  2. Breaking parameters of the page by trying to hack it
  3. Error from wrong user data input.
  4. Totally Unknown error - a new bug that we must fix.
  5. a Very hard General error - nothing runs - eg, database is not opens at all.

Our Goal

To now show the error page, but only in rare cases.

So when user make actions with out page, we try to capture all wrong input of the user, and show him what to do to continue with out any error.

Global Error Handler

You can start by capture on global.asax all errors using the void Application_Error(object sender, EventArgs e)

void Application_Error(object sender, EventArgs e) 
{
    try
    {
        Exception LastOneError = Server.GetLastError();

        if (LastOneError != null)
        {
            Debug.Fail("Unhandled error: " + LastOneError.ToString());

            if (!(EventLog.SourceExists(SourceName)))
                EventLog.CreateEventSource(SourceName, LogName);

            EventLog MyLog = new EventLog();
            MyLog.Source = SourceName;
            StringBuilder cReportMe = new StringBuilder();

            cReportMe.Append("[Error come from ip:");
            cReportMe.Append(GetRemoteHostIP());
            cReportMe.Append("] ");
            cReportMe.Append("Last Error:");
            cReportMe.Append(LastOneError.ToString());

            if (LastOneError.ToString().Contains("does not exist."))
            {
                // page not found
                MyLog.WriteEntry(cReportMe.ToString(), EventLogEntryType.Warning, 998);
            }
            else
            {
                MyLog.WriteEntry(cReportMe.ToString(), EventLogEntryType.Error, 999);
            }               
        }
    }
    catch (Exception ex)
    {
        Debug.Fail("Unhandled error: " + GlobalFun.GetErrorMessage(ex));
    }

    string cTheFile = HttpContext.Current.Request.Path;

    // to avoid close loop and stackoverflow
    if(!cTheFile.EndsWith("error.aspx"))
        Server.Transfer("~/error.aspx");
}

This global error handle have one main goal, to tell me whats is not working and fail to handle it before reach here, so I log it (not manner the way of log it) and fix it soon. When I debug my code I did not make the server transfer to be able to locate the error fast.

For the hacking error case

In this case is better to now show any error but just reload the page by making a redirect. How to know if its trying to hack the page ?

If on post back you get some CRC/hach error of your parameters you know that. Look that answer https://stackoverflow.com/a/2551810/159270 to see an example of a viewstate error and how to handle it.

I know that MVC did not have viewstate, but you may have other encrypted string on your code, or some kind of security that you can know when its broken. This is the general idea:

if(IsPostBack && HashErrorOnParametres)
{
  LogIt();
  Responce.Redirect(Request.RawUrl, true);
  return;
}

For a very hard General Error

Let say that your database is not open at all, then all users start to see the error page from the general handler. There you may have an extra option to restart the pool, or stop the pages after 20 errors in the last 5 minute, or something similar, and send you email to run and fix this very hard error.

For the rest soft errors

I think that all the possible known errors must be handled inside the page using try/catch and show to the user a message for what go wrong, if this error is from the user, and of course log it to see it and fix it.

Breaking the page in parts, maybe one part is throw the error and the rest working good, if this is not so important you can simple hide this part, and show the rest, until you fix it. For example if you just show information's about a product, and a part that speak about one part is throw an error, you can simple hide this part and see it on the log and fix it.

Some time I was try to handle the error per page, using protected override void OnError(EventArgs e) but this is not help me, and I remove it. I handle the errors per action, and if they are not critical I hide them until I fix them.

The rest normal errors is shown on the user, eg is not entered the correct data... a message for that and tell them what to fix.

As I say, my goal is to not show the error page at all.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...