I have a custom error page in an Azure ASP.NET web app where I'd like to display
<p>Oops - something went wrong.</p>
<p>The most common problem is that you tried to do something that the database enforces shouldn't happen.</p>
<p>The error is:</p>
In web.config I have:
<customErrors mode="On" defaultRedirect="Error.aspx" />
and global.asax:
protected void Application_Error(object sender, EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
string err = "Error Caught in Application_Error event\n" +
"Error in: " + Request.Url.ToString() +
"\nError Message:" + objErr.Message.ToString() +
"\nStack Trace:" + objErr.StackTrace.ToString();
EventLog.WriteEntry("Sample_WebApp", err, EventLogEntryType.Error);
}
Problem: How to display the full exception on the Error.aspx page?
Try adding redirectMode="ResponseRewrite" attribute to the customErrors element if you are using ASP.NET 3.5 SP1. That should preserve the exception information stored in Server.GetLastError(). Then you can add a label to the Error.aspx page and display the exception details, i.e. lblError.Text = Server.GetLastError().ToString().
Here's a similar SO question: ASP.NET custom error page - Server.GetLastError() is null
Related
I am using ASP.NET custom error page in my application. Following is the web.config file entry for CustomErrors tag
<customErrors mode="On" defaultRedirect="Error.aspx" redirectMode="ResponseRewrite" />
Following is the code snippet on Error.aspx page
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Exception ex = Server.GetLastError();
if(ex != null)
{
CommonUtils.SendException(ex.Message.ToString(), ex.StackTrace.ToString());
Server.ClearError();
}
}
}
If "ex" is not null, code will send the exception email. This works fine.
After sending email, I want to clear all the errors so that no email will be sent in case users hits the refresh button. But even after using Server.ClearError, there is a value return by Server.GetLastError() When page is posted back.
Your code should be rewritten to something like this:
Global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
Exception ex= Server.GetLastError();
CommonUtils.SendException(ex.Message.ToString(), ex.StackTrace.ToString());
}
And the Page_Load event of error page should be empty then. As you can read in this MS article: https://support.microsoft.com/en-us/kb/306355 Server.ClearErrors stops error propagation, so If you call it on the page error will not be handled by Application_Error event. If you don't call it in Application_Error then application will look for customErrors declaration in web.config redirect to that page.
If you do not call Server.ClearError or trap the error in the
Page_Error or Application_Error event handler, the error is handled
based on the settings in the section of the Web.config
file. In the section, you can specify a redirect page
as a default error page (defaultRedirect) or specify to a particular
page based on the HTTP error code that is raised. You can use this
method to customize the error message that the user receives.
If an error occurs that is not trapped at any of the previous levels
in your application, this custom page is displayed. This section
demonstrates how to modify the Global.asax file so that
Server.ClearError is never called. As a result, the error is handled
in the Web.config file as the last point to trap the error.
In my ASP.NET MVC project I have the /errors/error.html page as a general error page and a second /errors/error404.aspx that handles the 404 errors.
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="/errors/error.html">
<error statusCode="404" redirect="/errors/error404.aspx" />
</customErrors>
Also, I have in my Global.asax file a general handler that logs all uncaught exceptions for logging purposes.
public void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Common.Core.LogError(ex); // Saving exception details in the database
}
The above setup works well except for when I have a general error (e.g. a 500 error) the Application_Error logs this error below:
The view 'Error' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/app/Error.aspx
~/Views/app/Error.ascx
~/Views/Shared/Error.aspx
~/Views/Shared/Error.ascx
~/Views/app/Error.cshtml
~/Views/app/Error.vbhtml
~/Views/Shared/Error.cshtml
~/Views/Shared/Error.vbhtml
The Exception from the actual error is not logged at all.
How can I avoid this error?
P.S. For anyone who might ask, I tried to put my error pages as views inside a controller but also I couldn't make it work with the redirectMode="ResponseRewrite" option.
You are trying to handle errors in a non-ASP.NET MVC way, in an ASP.NET MVC project. To resolve your issue, you could comment the line filters.Add(new HandleErrorAttribute()); in the FilterConfig.cs file. See the snippet below.
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
}
}
I make a code with the session in the payload I test if the error exist :
protected void Page_Load(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(Session["id"].ToString())) QueryStringError.SessionNotFound(Response);
else
{
I redirect to some page if the session is not exist ... but I got these error after some period of time :
Server Error in '/Redcrescent' Application.
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 11: protected void Page_Load(object sender, EventArgs e)
Line 12: {
Line 13: if (String.IsNullOrEmpty(Session["id"].ToString())) QueryStringError.SessionNotFound(Response);
Line 14: else
Line 15: {
Source File: c:\Users\Samy\Documents\Visual Studio 2010\WebSites\Redcrescent\User\UserPrivilegeManage.aspx.cs Line: 13
the session timeout is finish but why it gave me the error it should redirect not throw an error
in web.config file :
<sessionState cookieless="true"
regenerateExpiredSessionId="true"
timeout="525600" mode="InProc" stateNetworkTimeout="525600"
/>
but still didn't work ... any idea ?
how to make session never expired ? and how to solve these error ?
You should check for session key first like:
if(Session["id"]!= null)
And then call its ToString method. The reason you are getting the exception (NRE) is because the key doesn't exits in session and you are trying to call ToString on it.
You cannot execute ToString on null but exactly this you're doing if the session value is null here:
if (String.IsNullOrEmpty(Session["id"].ToString())) QueryStringError.SessionNotFound(Response);
You need to check for null separately:
object id = Session["id"];
if(id == null || String.IsNullOrEmpty(id.ToString())
{
QueryStringError.SessionNotFound(Response);
}
replace
if (String.IsNullOrEmpty(Session["id"].ToString()))
with
if (String.IsNullOrEmpty(Session["id"]))
How can I replace the standard error page in the case the request length exceeds the one specified in maxQueryStringLength and show the user something more friendly?
Note: Although as an HttpException this falls into generic 400th error, I want to separate the QueryLength condition and show a very specific page for this specific error. So, I cannot use "customErrors" section to indicate a page, but rather need to filter this programmatically. The problem with the below is it doesn't work.
protected virtual void Application_Error(Object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (logs != null) logs.ExceptionMsg("Application exception", this, ex);
var httpex = ex as System.Web.HttpException;
if (httpex != null && httpex.ErrorCode == -2147467259)
{
Server.ClearError();
Server.TransferRequest(#"~/main/maxlengthexceeded", false);
}
}
The problem is that Server.TransferRequest does not work. Is there an alternative to how I can tell ASP.NET which page to load?
if you are able to catch the error type/number you are getting, then you can configure a different error/redirect page only for that, here an example of configuration in the web.config:
<configuration>
<system.web>
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly">
<error statusCode="500"
redirect="InternalError.htm"/>
</customErrors>
</system.web>
</configuration>
you can see the full article here: Displaying a Custom Error Page
First of all, quickly what exactly I want to achieve: translate particular exception into the HTTP 404 so the ASP.NET can handle it further.
I am handling exceptions in the ASP.NET (MVC2) this way:
protected void Application_Error(object sender, EventArgs e) {
var err = Server.GetLastError();
if (err == null)
return;
err = err.GetBaseException();
var noObject = err as ObjectNotFoundException;
if (noObject != null)
HandleObjectNotFound();
var handled = noObject != null;
if (!handled)
Logger.Fatal("Unhandled exception has occured in application.", err);
}
private void HandleObjectNotFound() {
Server.ClearError();
Response.Clear();
// new HttpExcepton(404, "Not Found"); // Throw or not to throw?
Response.StatusCode = 404;
Response.StatusDescription = "Not Found";
Response.StatusDescription = "Not Found";
Response.Write("The whole HTML body explaining whata 404 is??");
}
The problem is that I cannot configure default customErrors to work with it. When it is on then it never redirects to the page specified in customErrors: <error statusCode="404" redirect="404.html"/>.
I also tried to raise new HttpExcepton(404, "Not Found") from the handler but then the response code is 200 which I don't understand why.
So the questions are:
What is the proper way of translating AnException into HTTP 404 response?
How does customErrors section work when handling exceptions in Application_Error?
Why throwing HttpException(404) renders (blank) page with success (200) status?
Thanks,
Dmitriy.
In a few words, you if you manually set HTTP status in Application_Error, you lose possibility to use customErrors section handler, since you call Server.ClearError().
Handle the exception before Application_Error or derive the exception from HttpException.
What is the proper way of translating AnException into HTTP 404 response?
It's better to handle exceptions in Controller. You can introduce base class controller and handle most of exceptions in custom HandleError attribute. You can throw HttpException their and it will be properly handled by customErrors section handler.
You can also derive your ObjectNotFoundException exception from HttpException(404)
Application_Error is the last chance to handle an exception. You have only Response API to handle it. You can manually set status code and write to response or manually trigger redirect to custom error page or call Server.TransferRequest() to existing html or aspx file (not to the controller action). In current asp.net version, you cannot set or change Server.GetLastError in Application_Error method only retrieve or clear it.
How does customErrors section work when handling exceptions in Application_Error?
By calling Server.ClearError() you also clean current request error therefore it is not handled by customErrors section handler
Why throwing HttpException(404) renders (blank) page with success (200) status?
You should no throw any exception in Application_Error method. Exception means that your error handling failed.