I'm defining a custom Error page in ASP.NET
<customErrors mode="RemoteOnly" defaultRedirect="Oops.aspx"></customErrors>
When an Error occurs, I'm being redirect to that page with the following URL:
Oops.aspx?aspxerrorpath=/WebForm1.aspx
In the Page Load method of the Oops.aspx page, I'm trying to catch the error:
Exception exc = Server.GetLastError();
if (exc != null)
{
//do something
}
However, it seems that exc is actually null because none of the actions defined in that condition statement are being executed.
If you are logging the error in a datastore, the best way you can achieve this is by logging that error in Application_Error method of Global.asax, and then redirect to the Oops.aspx?refId=yourerrorId with the key of the error record that was stored in the datastore.
Related
My MVC 5 web application running on Azure Cloud Service crashed with an unhandled exception "A potentially dangerous Request.Path value was detected from the client (:)".
The cause for this crash was some third party (maybe malicious) hit my endpoints with url:
http://myExampleHost.com/m:443/templates
The colon in the url cannot pass the path validation.
Some answers (A potentially dangerous Request.Path value was detected from the client (*)) suggest change the validate rules. However, out of security concerns, we may not want to compromise on this.
The ideal behavior for it that: we catch the exception, log it and return some error messages without crashing. How should we do that?
A more general question on this would be: how to catch an exception before the request hits controllers in MVC?
The ideal behavior for it that: we catch the exception, log it and return some error messages without crashing. How should we do that?
Per my understanding, you could leverage the Application_Error event to capture unhandled exception(s) within ASP.NET. Here is my test, you could refer to it:
protected void Application_Error()
{
HttpContext httpContext = HttpContext.Current;
var exception=Server.GetLastError();
var httpException = exception as HttpException ?? new HttpException(500, "Internal Server Error", exception);
var jsonResponse = new
{
Message = exception.Message,
StatusCode = httpException.GetHttpCode(),
StackTrace=httpException.StackTrace
};
httpContext.Response.ContentType = "application/json";
httpContext.Response.ContentEncoding = Encoding.UTF8;
httpContext.Response.Write(JsonConvert.SerializeObject(jsonResponse));
httpContext.Response.End();
}
Note: You could also redirect to a specific error page.
Moreover, you could leverage the customErrors in web.config and catch the error page for the specific HTTP error code. Also, you could check the HTTP status code under the Application_EndRequest event and write your custom response, details you could refer to this similar issue. Additionally, I would recommend you follow Demystifying ASP.NET MVC 5 Error Pages and Error Logging for more details about error handling.
I have set up my custom error page which work fine:
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="500" redirect="~/Pages/ErrorPages/500.aspx" />
</customErrors>
On 500.aspx:
Response.ClearContent();
Response.StatusCode = 500;
Exception = Server.GetLastError();
Code.Errors.Error.RecordNewError(ErrorType.InternalException, Exception, Code.Common.GetUserIPAddress().ToString(), HttpContext.Current);
Server.ClearError();
Problem is, if the error page throws an error itself we get an ugly error:
Runtime Error
Description: An exception occurred while processing your request.
Additionally, another exception occurred while executing the custom
error page for the first exception. The request has been terminated.
How do I fall back to a more basic custom error page if the error page itself throws an error?
Figured it out just now! Use the Page_Error method on the error pages themselves:
private void Page_Error(object sender, EventArgs e)
{
Response.ClearContent();
Response.StatusCode = 500;
Exception = Server.GetLastError();
HttpContext.Current.Response.Write("Error");
HttpContext.Current.Response.End();
}
I was looking for a way to transfer the exception message in web services of my asp.net application to the ajax error callback function.
All I could find was catching an exception thrown from web service into a C# code but i am calling my service from ajax code and not a C# code. I want something more than the HTTP status codes returned.
Here is catch block of my Service code:
catch (Exception ex)
{
var fault = new GenericFault { Message = ex.Message, Operation = "" };
throw new FaultException<GenericFault>(fault);
}
}
And here is my ajax error callback:
error: function (err) {
alert("The server encountered an error, please resubmit your request. If the problem persists, contact your administrator.");
return 'error occured';
}
I have already tried throwing web fault exception but that also didn't serve the purpose as only the HTTP status code gets passed.
Found an answer. The trick lies in throwing right exception.
As the error caught in the callback error function sees the details in xhr object.
So you need to throw the HttpException passing with it status code and string message.
catch block should look something like:
catch (Exception ex)
{
throw new HttpException(500, ex.Message);
}
then your ajax callback will get the ex.message that you are passing from here:
error: function (err) {
alert("The Detailed server error is "+err.responseJSON.Message);
return 'error occured';
}
I am trying to add the Application_Error method into the Global.asax file, but I am getting a parser error:
Server Error in '/' Application. Parser Error Description: An error
occurred during the parsing of a resource required to service this
request. Please review the following specific parse error details and
modify your source file appropriately.
Parser Error Message: The content in the application file is not
valid.
I do not understand why it this method is not working. Any help is appreciated thanks!
<%#Application Language='C#' Inherits="Sitecore.Web.Application" %>
using System.Configuration;
protection void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
// Get the exception object.
Exception exc = Server.GetLastError();
// Handle HTTP errors
if (exc.GetType() == typeof(HttpException))
{
// The Complete Error Handling Example generates
// some errors using URLs with "NoCatch" in them;
// ignore these here to simulate what would happen
// if a global.asax handler were not implemented.
if (exc.Message.Contains("NoCatch") || exc.Message.Contains("maxUrlLength"))
return;
//Redirect HTTP errors to HttpError page
Server.Transfer("HttpErrorPage.aspx");
}
// For other kinds of errors give the user some information
// but stay on the default page
Response.Write("<h2>Global Page Error</h2>\n");
Response.Write(
"<p>" + exc.Message + "</p>\n");
Response.Write("Return to the <a href='Default.aspx'>" +
"Default Page</a>\n");
// Log the exception and notify system operators
ExceptionUtility.LogException(exc, "DefaultPage");
ExceptionUtility.NotifySystemOps(exc);
// Clear the error from the server
Server.ClearError();
}
I think that you should add the code in the .cs file.
Moreover protection is not accepted. Your code should be like this:
void Application_Error(object sender, EventArgs e)
{
//DoSomething();
}
I have the following error in my output.aspx page sometimes:
Exception Details: System.Web.HttpException: Request timed out.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): Request timed out.]
Is it a good idea to catch this exception? Where do I do that as my output.aspx.cs has a Page_Load and that function calls RunTable(). Should I put a try catch block around that functions content?
catch exception at application level
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
// Get the exception object.
Exception exc = Server.GetLastError();
// Handle HTTP errors
if (exc.GetType() == typeof(HttpException))
{
// The Complete Error Handling Example generates
// some errors using URLs with "NoCatch" in them;
// ignore these here to simulate what would happen
// if a global.asax handler were not implemented.
if (exc.Message.Contains("NoCatch") || exc.Message.Contains("maxUrlLength"))
return;
//Redirect HTTP errors to HttpError page
Server.Transfer("HttpErrorPage.aspx");
}
// For other kinds of errors give the user some information
// but stay on the default page
Response.Write("<h2>Global Page Error</h2>\n");
Response.Write(
"<p>" + exc.Message + "</p>\n");
Response.Write("Return to the <a href='Default.aspx'>" +
"Default Page</a>\n");
// Log the exception and notify system operators
ExceptionUtility.LogException(exc, "DefaultPage");
ExceptionUtility.NotifySystemOps(exc);
// Clear the error from the server
Server.ClearError();
}