getting those built in error pages

L

Larry Tate

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
 
R

Rick Strahl [MVP]

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/
 
L

Larry Tate

That looks cool. What methods are you calling to get all of this info? I can
write a parser to chew through it.

Thanks,
Larry



Rick Strahl said:
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
 
R

Rick Strahl [MVP]

Ah, sorry forgot that. Server.GetLastError() and then use the
InnerException. LastError is basically the Exception that is being parsed
and it's set by the constructor. My class basically parses an exception and
generates the error page from that and then dumps a few of the critical
server vars along with that.

+++ Rick ---

--

Rick Strahl
West Wind Technologies
http://www.west-wind.com/
http://www.west-wind.com/webblog/
----------------------------------
Making waves on the Web


Larry Tate said:
That looks cool. What methods are you calling to get all of this info? I can
write a parser to chew through it.

Thanks,
Larry



Rick Strahl said:
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


I
hit
get
 
L

Larry Tate

I hate to keep asking questions on this .... :(

How do I implement this? The main reason I ask is because I am using vb.net.
I should be able to convert it..
Also the function is a boolean with no input.

Do I just call this from like the global.asax file?
sub application_error(sender As Object, e As EventArgs)
Parse()
end sub


Thanks,
Hate to be such a pain.
Larry


Rick Strahl said:
Ah, sorry forgot that. Server.GetLastError() and then use the
InnerException. LastError is basically the Exception that is being parsed
and it's set by the constructor. My class basically parses an exception and
generates the error page from that and then dumps a few of the critical
server vars along with that.

+++ Rick ---

--

Rick Strahl
West Wind Technologies
http://www.west-wind.com/
http://www.west-wind.com/webblog/
----------------------------------
Making waves on the Web


Larry Tate said:
That looks cool. What methods are you calling to get all of this info? I can
write a parser to chew through it.

Thanks,
Larry
string.Format("http://{0}{1}",Request.ServerVariables["SERVER_NAME"],RequestEncoding.GetEncoding(1252).GetString(Request.BinaryRead(Request.TotalBytes))
can
be EventArgs
e)
when
I get of
the or
the
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top