Hi Larry,
Yeah, it's possible but you have to do a little work. You can only get this
info if you have the source code, which in a production app is unlikely.
I have built an WebErrorHandler class that pretty much does what you're
looking for - it generates a detailed error message and logs it and then
also sends an email out with the info.
To get the info you're looking for, you can look at the Server.StackTrace.
Here's is the key method called Parse from the error handler that takes
common error info and drops it into properties of the WebErrorHandler
object. It includes code to pull the source code if available:
public bool Parse()
{
if (this.LastError == null)
return false;
IsParsed = true;
// *** Use the Inner Exception since that has the actual error info
HttpRequest Request = HttpContext.Current.Request;
this.RawUrl = Request.RawUrl;
if ( LastError is System.IO.FileNotFoundException)
this.ErrorMessage = "File not found: " + LastError.Message;
else
this.ErrorMessage = LastError.Message;
this.Time = DateTime.Now;
if (this.CompactFormat)
return true;
this .StackTrace = LastError.StackTrace;
if (this.RetrieveSourceLines)
{
StringBuilder sb = new StringBuilder(1024);
// *** Try to retrieve Source Code information
StackTrace st = new StackTrace(LastError,true);
StackFrame sf = st.GetFrame(0);
if (sf != null)
{
string Filename = sf.GetFileName();
if (RetrieveSourceLines && Filename != null)
{
int LineNumber = sf.GetFileLineNumber();
if (LineNumber > 0)
{
StreamReader sr = new StreamReader(Filename);
// *** Read over unwanted lines
int x = 0;
for (x = 0; x < LineNumber - 4; x++ )
sr.ReadLine();
sb.Append("--- Code ---\r\n");
sb.AppendFormat("File: {0}\r\n",Filename);
sb.AppendFormat("Method: {0}\r\n\r\n",LastError.TargetSite);
sb.AppendFormat("Line {0}: {1}\r\n",x + 1,sr.ReadLine());
sb.AppendFormat("Line {0}: {1}\r\n",x + 2,sr.ReadLine());
sb.AppendFormat("Line {0}: {1}\r\n",x + 3,sr.ReadLine());
sb.AppendFormat("<b>Line {0}: {1}</b>\r\n", x+
4,sr.ReadLine() );
sb.AppendFormat("Line {0}: {1}\r\n",x +5,sr.ReadLine());
sb.AppendFormat("Line {0}: {1}\r\n",x +6,sr.ReadLine());
sb.AppendFormat("Line {0}: {1}\r\n",x +7,sr.ReadLine());
sr.Close();
}
}
}
this.SourceCode = sb.ToString();
}
this.FullUrl =
string.Format("http://{0}{1}",Request.ServerVariables["SERVER_NAME"],Request
.RawUrl);
this.IPAddress = Request.UserHostAddress;
if (Request.UrlReferrer != null)
this.Referer = Request.UrlReferrer.ToString();
this.Browser = Request.UserAgent;
if (Request.IsAuthenticated)
this.Login = HttpContext.Current.User.Identity.Name;
else
this.Login = "Anonymous";
if (Request.TotalBytes > 0 && Request.TotalBytes < 2048)
{
this.PostBuffer =
Encoding.GetEncoding(1252).GetString(Request.BinaryRead(Request.TotalBytes))
;
this.ContentSize = Request.TotalBytes;
}
else if (Request.TotalBytes > 2048) // strip the result
{
this.PostBuffer =
Encoding.GetEncoding(1252).GetString(Request.BinaryRead(2048)) + "...";
this.ContentSize = Request.TotalBytes;
}
return true;
}
The class then wrappers everything up into a single text string that can be
logged and emailed but that's pretty trivial. The final result looks
something like this:
/wwWebstore/admin/ErrorTestPage.aspx
Object reference not set to an instance of an object.
on 12/19/2003 8:47:57 pm
--- Stack Trace ---
at Westwind.WebStore.ErrorTestPage.Page_Load(Object sender, EventArgs e)
in
d:\projects\wwWebStore\Admin\ErrorTestPage.aspx.cs:line 26
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain()
--- Code ---
File: d:\projects\wwWebStore\Admin\ErrorTestPage.aspx.cs
Method: Void Page_Load(System.Object, System.EventArgs)
Line 23:
Line 24: // Now explicitly set this value to null
Line 25: Invoice = null;
<b>Line 26: Invoice.GetBlankRecord();</b>
Line 27: }
Line 28:
Line 29: #region Web Form Designer generated code
--- Request Information ---
Full Url:
http://localhost/wwWebstore/admin/ErrorTestPage.aspx
IP: 127.0.0.1
Referer:
http://localhost/wwWebstore/admin/
Browser: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR
1.1.4322; .NET CLR 1.2.30703)
Login: RASNOTEBOOK\rstrahl
Note on the server the source code won't be there so it can't be
retrieved.+++ Rick ---
--
Rick Strahl
West Wind Technologies
http://www.west-wind.com/
http://www.west-wind.com/blog/
----------------------------------
Making waves on the Web
Larry Tate said:
I am wanting to get those cool html error pages that ms produces when I hit
an error in asp.net. For instance, when I get a compilation error I get an
html error page that shows me the
Description:
Compiler Error Message:
Source Error:
Source File:
The main thing I want is the Source Error. This give me a few lines of the
code with line numbers.
The other thing is the Compiler Error. This gives me the, "var1 not
declared" or something, error.
Ideally I would like to shoot the html page to my email.
Is this possible.
FYI .... I have this already in the global file.
Dim ex As Exception = Server.GetLastError()
request.path
ex.Message
ex.StackTrace
ex.Source
Request.Form.ToString()
Request.QueryString.ToString()
ex.TargetSite.ToString()
ex.ToString()
All of which is emailed to me and does not include the line number or the
Compiler Error Message.
Any ideas?
Thanks,
Larry