I'm using the customErrors attribute of the web.config file to present custom errors pages:
<customErrors mode="On" defaultRedirect="/errorpage.aspx">
<error statusCode="404" redirect="/404Page.aspx"/>
<error statusCode="403" redirect="/403page.aspx"/>
</customErrors>
Nothing too fancy. Now what I want to do is log the error that occurs when any of these pages are loaded. I'm specifically interested in any exceptions, I don't really care what page the user was on when they got a 404.
I'd like to capture the exception and record it into a db Table. Will something like this work:
//errorpage.aspx
public void Page_Load(object sender,EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
var err = new {Url = Request.Url.ToString(),
Message = objErr.Message,
Trace = objErr.StackTrace.ToString()};
db.Errors.InsertOnSubmit(err);
db.SubmitChanges();
Server.ClearError();
}
Is there any other information that is worth capturing, or is generally captured on an error?
I think there are better ways to do this:
Use ELMAH!
Run your code in the Global.asax Application_Error event.
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError().GetBaseException();
EventLog.WriteEntry("Test Web",
"MESSAGE: " + ex.Message +
"\nSOURCE: " + ex.Source +
"\nFORM: " + Request.Form.ToString() +
"\nQUERYSTRING: " + Request.QueryString.ToString() +
"\nTARGETSITE: " + ex.TargetSite +
"\nSTACKTRACE: " + ex.StackTrace,
EventLogEntryType.Error);
}
Rather than rolling your own, have you considered using something like Elmah, which can handle this all for you:
http://www.hanselman.com/blog/ELMAHErrorLoggingModulesAndHandlersForASPNETAndMVCToo.aspx
Why don't you simply use the application server log, what happed if the error/exception is due to the impossibility of accessing the data base. Here is how I log the errors in some web site:
public static void WriteException(Exception exception)
{
EventLog eventLog = null;
try
{
StringBuilder message = new StringBuilder();
message.Append("[").Append(exception.Source).Append(" - ").Append(exception.GetType().FullName);
message.Append("]").Append(#"\r\n").Append(exception.ToString());
eventLog = new EventLog();
eventLog.Log = "LOG_FILE_NAME";
eventLog.Source = "APP_IDENTIFIER";
eventLog.WriteEntry(message.ToString(), EventLogEntryType.Warning);
}
catch (Exception ex) {/*DO-NOTHING*/ string msg = ex.Message; }
finally { if (eventLog != null) { eventLog.Dispose(); } eventLog = null; }
}
Related
i've got a bit of a problem trying to set up a general error page in MVC.
I am handling all app errors in Global.asax.cs with the following code ->
protected void Application_Error(object sender, EventArgs e)
{
//if (Request.Url.ToString().StartsWith("http://localhost:"))
// return;
string msg;
Exception ex = Server.GetLastError().GetBaseException();
StringBuilder sb = new StringBuilder();
sb.AppendLine("Exception Found");
sb.AppendLine("Timestamp: " + System.DateTime.Now.ToString());
sb.AppendLine("Error in: " + Request.Url.ToString());
sb.AppendLine("Browser Version: " + Request.UserAgent.ToString());
sb.AppendLine("User IP: " + Request.UserHostAddress.ToString());
sb.AppendLine("Error Message: " + ex.Message);
sb.AppendLine("Stack Trace: " + ex.StackTrace);
msg = sb.ToString();
Server.ClearError();
Response.Redirect(string.Format("~/Error/Error?w={0}", msg ));
}
My problem is that i'm not getting a redirect. I see the same page URL and a blank page when i'm creating an error.
If i remove "errorMsg" and add a SIMPLE STRING, it works, redirects with the required param. Ex:
string test = "testme";
Response.Redirect(string.Format("~/Error/Error?w={0}", test));
That does redirect me to the error page with param "testme". What am i doing wrong here?
You to need escape all the parameters (UrlEncode). At the moment it is unescaped and has a whole bunch of new lines too.
Before you do that, I suggest you just append "hello world" parameter and re-display that to ensure your redirect page is working
I have this weird error. When I call System.IO.File.Delete(), it throws
JobCleaner.CleanFiles(): Unable to delete file: D:\WorkerData\4\Run128\Run_TEMPLATE_Rail_Scenario_Type35_INFHD2_NO_TAX_NOMEP\output_panels\FileIndex55.bin
Error: Arithmetic operation resulted in an overflow.
There is no stack trace.
Here is my code:
foreach (string strFile in System.IO.Directory.GetFiles(strFolder))
{
try { System.IO.File.Delete(strFile); }
catch (Exception ex)
{
//Exception here
AddToLog("JobCleaner.CleanFiles(): Error occurred when trying to delete file \"" + strFile + "\".\nError:\n" + ex.Message);
return false;
}
}
Any idea? I tried everything, I check the security on the folder. I enabled "Everyone" with full controls, but still encounter this "Arithmetic operation resulted in an overflow" exception.
Can anyone help, please? I am using Windows 2012 R2 Datacenter to run my application.
I wouldn't expect it to throw an arithmetic exception, but I have observed some weird behavior when you modify an IEnumerable within the foreach that is walking it. Try moving the file listing out of the loop, like this:
string[] files = System.IO.Directory.GetFiles(strFolder);
foreach (string strFile in files)
{
try { System.IO.File.Delete(strFile); }
catch (Exception ex)
{
//Exception here
AddToLog("JobCleaner.CleanFiles(): Error occurred when trying to delete file \"" + strFile + "\".\nError:\n" + ex.Message);
return false;
}
}
I'm I'm trying to upload a file to my server via FTP, and it's not working. The Upload complete event is triggered, and there are no exceptions being caught by the try catch block. This should be pretty straightforward right? What am I missing here? I know the web directory is right, because I copied and pasted it right from my browser after navigating to it, and the file that I'm uploading is correct because it makes it past the File.Exists, if statement.
string strWebDirectory = "ftp://sharedhosting.com/mydomain.com/wwwroot/Images/" + txt.Text.Trim();
System.Net.WebClient wc = new System.Net.WebClient();
wc.Credentials = new System.Net.NetworkCredential("usr", "psw");
wc.UploadFileCompleted += (s, ev) => UploadProgressCompleted();
if (File.Exists( strStartUpPath + "Upload\\" + txtFile.Text))
{
try
{
wc.UploadFileAsync(new Uri(strWebDirectory), strStartUpPath + "Upload\\" + txtFile.Text);
}
catch (Exception ex)
{
}
}
Any help is appreciated. Thank you.
Look at the Error property. Probably, there was an error.
You need to await/wait on UploadFileAsync to observe the exception it is throwing.
try
{
await wc.UploadFileAsync(new Uri(strWebDirectory), strStartUpPath + "Upload\\" + txtFile.Text);
}
catch (Exception ex)
{
}
I am trying to catch an exception when my XSD is invalid and just display a message on the console detailing to the user what went wrong. However the message that is displayed on the console is not as I expected.
try
{
// doing stuff here
}
catch (XmlException e)
{
Console.WriteLine("ERROR: Schema " + e.Message);
return false;
}
I expected the output to be something like:
"ERROR: Schema ' is an unexpected token. The expected token is '>'. Line 15, position 38."
However the output that I get is:
"' is an unexpected token. The expected token is '>'. Line 15, position 38."
My string at the beginning is not displayed before the message.
I have tried storing the values in two strings and tried concatenating those 2 string with no success. Ideally I would like one string that contains the concatenation of both the 'ERROR' part and the message produced by the exception.
I think your schema contains a newline. The text ERROR: Schema ' must be somewhere higher in the output window.
You can check this using:
catch (XmlException e)
{
string message = "ERROR: Schema " + e.Message;
message = message.Replace(Environment.NewLine, "");
message = message.Replace("\n", "");
message = message.Replace("\r", "");
Console.WriteLine(message);
return false;
}
Try with:
try
{
// doing stuff here
}
catch (XmlException e)
{
errorMessage = "ERROR: Schema " + e.Message.toString();
Console.WriteLine(errorMessage );
return false;
}
I'm using the following code in my global.asax file:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception objErr = Server.GetLastError().GetBaseException();
string err = "Error Caught in Application_Error event<hr />" + "Current User: " + HttpContext.Current.User.Identity.Name + "<hr />" +
"Error in: " + Request.Url.ToString() +
"<hr />Error Message:" + objErr.Message.ToString() +
"<hr />Stack Trace:" + objErr.StackTrace.ToString();
//EventLog.WriteEntry("Sample_WebApp", err, EventLogEntryType.Error);
doEmail.sendEmail("Application Error - Curato (" + System.Configuration.ConfigurationManager.AppSettings["OrganisationName"].ToString() + ")", err);
// We do not want the error handled by the web.config as well, so clear the error.
Server.ClearError();
// Now redirect ourselves...
Response.Redirect("~/error.aspx?aspxerrorpath=" + Server.UrlEncode(Request.Url.PathAndQuery));
}
This sends the stackTrace and current user to an admin email address, and redirects the user to a friendly error page.
How would I be able to include the full Trace information in err? That is, the same information as if I had set Trace="True" in the <%# Page directive.
I'm exploring the Trace object - and found how to read it from a 3rd party reader how to read trace but I'd like to read it just in native code.
You're already getting the full StackTrace of the exception, I believe you're looking at the wrong Exception object:
I think your error is in this line:
Exception objErr = Server.GetLastError().GetBaseException();
I think the correct one should be:
Exception objErr = Server.GetLastError();
You can also inspect the exception to see if there are InnerException:
if (objErr.InnerException != null)
err = err + "<hr/>Message:" + objErr.InnerException.Message;
See this question also:
Application_Error - GetLastError() or GetLastError().GetBaseException()