Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Session Objects 1

Status
Not open for further replies.

Rhys666

Programmer
May 20, 2003
1,106
0
0
I hate session objects, I hate default error pages - they just don't work properly!!! Yes I'm currently very frustrated...

I'm trying to capture and display errors on a generic page if they're not handled as it's simply not possible to cope with all exception types in every try...catch block.

I've done this previously by playing with Global.asax.cs, adding functionality to protected void Application_Error as below;
Code:
protected void Application_Error(Object sender, EventArgs e)
{
// At this point we have information about the error
HttpContext ctx = HttpContext.Current;

Exception exception = ctx.Server.GetLastError();

string errorInfo = 
    "<br>Offending URL: " + ctx.Request.Url.ToString() + "<br>" +
    "<br>Source: " + exception.Source + "<br>" +
    "<br>Inner Exception: " + exception.InnerException + "<br>" +
    "<br>Message: " + exception.Message + "<br>" +
    "<br>Stack trace: " + exception.StackTrace;

Session.Add("Error",errorInfo);
// To let the page finish running we can clear the error
// ctx.Server.ClearError ();
}

then redirecting the page to my error page, reading the error from the session object and simply writing it to a control. I.e.,
Code:
if (Session["Error"] != null)
{
    this.lblError.Text = Session["Error"].ToString();
    Session.Remove("Error");
}

However, i'm currently getting a problem from the above. I can set up breakpoints so after I've added the error string to the session object I can retrieve it (?Session["Error"]) in the Command Window (in VS). However, when the page transfers to the generic error page, (which by stepping thru' I can see does happen after the errors been written to the session object), the Session["Error"] object evaluates as null - where has it gone?

Yes all the pages are part of the same project and solution, even the same namespace.

Even writing to a Session object from the page on which the error originates doesn't help as the session object evaluates as null by the time I get to my error page - any idea's, thoughts, workarounds or alternative solutions?

Just to confuse the issue I know the above functionality can work as I've had it working exactly as set out above in a different web application at a different company - hence some of my frustration at the moment!

Thanks in advance...

Rhys

""Vampireware /n/, a project, capable of sucking the lifeblood out of anyone unfortunate enough to be assigned to it, which never actually sees the light of day, but nonetheless refuses to die."

My Home
 
No need to mess around with Session State.
Here's my global.asax handler
Code:
protected void Application_Error(Object sender, EventArgs e)
		{
			if(Server.GetLastError() is HttpUnhandledException)
				Server.Transfer("~/errorPage.aspx");
		}
Here's the important part of the error page:
Code:
private void Page_Load(object sender, System.EventArgs e)
		{
			Exception ex = Server.GetLastError();
			if(ex != null)
			{
				try
				{
					StringBuilder sb = new StringBuilder();
					if(ex.InnerException != null)
					{
						sb.Append("Error: " + ex.InnerException.Message);
						sb.Append(Environment.NewLine);
						sb.Append("Source: " + ex.InnerException.Source.ToString());
						sb.Append(Environment.NewLine);
						sb.Append("User: " + BizHelp.LanID().ToString());
						sb.Append(Environment.NewLine);
						sb.Append(Environment.NewLine);
						sb.Append("Stack Trace: " + Environment.NewLine);
						sb.Append(ex.InnerException.StackTrace.ToString());
									
					}
					string[] strKeys;
					string[] strValues;
					string strControls = "";
					strKeys = Request.Form.AllKeys;

					for(int i = 0;i<Request.Form.Count;i++)
					{
						strValues = Request.Form.GetValues(i);
						for (int j = 0; j <= strValues.GetUpperBound(0); j++) 
						{
							if (strKeys[i] != "__VIEWSTATE")
								strControls += strKeys[i] + "=" +
									strValues[j] + "\r";
						}

					}
				
					/*
					Insert error to db and send email here.....
					*/
				}
				catch(Exception exp)
				{
					Response.Write("Error on page<br/>");
					Response.Write(exp.Message.ToString() + "<br/>");

				}
			
			
			}
		}
This routine captures everything that I need to know including the values that were currently entered by the user in any of the form controls. It's written to a db table and also emailed to me. The .aspx pages displays a generic error message to the user and lets them know that it will be taken care of.
 
The GetLastError() method was also returning null as well strangely enough, not in the Global.asax - that was fine, but in the error page. I've hacked my way around it by specifying exception actions on those I can expect i.e.,
Code:
try
{
  //Something
}
//Ooops, something broke
catch (Exception exc)
{
  //We could expect a formatting exception
  if (exc is System.FormatException)
  {
    ServerSideNumberFormatError(); //private method
  }
...and by creating an error class I can maintain exception information in the session, and destroy that particular session object after it's use...
Code:
-- End of Try..Catch --
  //But if it's anything else...
  else
  {
    MyNamespace.Error.HandleError(Session, exc);
    Server.Transfer("ErrorPage.aspx");
  }
}
--ErrorPage--
private void Page_Load(object sender, System.EventArgs e)
{
  // Put user code to initialize the page here
  if (MyNamespace.Error.ErrorExists)
  {
    this.lblError.Text = MyNamespace.Error.RetrieveError(Session);
  MyNamespace.Error.ClearError(Session);
  }
}

Rhys

""Vampireware /n/, a project, capable of sucking the lifeblood out of anyone unfortunate enough to be assigned to it, which never actually sees the light of day, but nonetheless refuses to die."

My Home
 
Hi Veep,

Can you please put the code for insertion into db and sending email as well. I would appreciate it. By the way, nice piece of work.

Thanks
 
Here's the whole thing:
Code:
private void Page_Load(object sender, System.EventArgs e)
		{
			Exception ex = Server.GetLastError();
			if(ex != null)
			{
				try
				{
					StringBuilder sb = new StringBuilder();
					if(ex.InnerException != null)
					{
						sb.Append("Error: " + ex.InnerException.Message);
						sb.Append(Environment.NewLine);
						sb.Append("Source: " + ex.InnerException.Source.ToString());
						sb.Append(Environment.NewLine);
						sb.Append("User: " + BizHelp.LanID().ToString());
						sb.Append(Environment.NewLine);
						sb.Append(Environment.NewLine);
						sb.Append("Stack Trace: " + Environment.NewLine);
						sb.Append(ex.InnerException.StackTrace.ToString());
									
					}
					string[] strKeys;
					string[] strValues;
					string strControls = "";
					strKeys = Request.Form.AllKeys;

					for(int i = 0;i<Request.Form.Count;i++)
					{
						strValues = Request.Form.GetValues(i);
						for (int j = 0; j <= strValues.GetUpperBound(0); j++) 
						{
							if (strKeys[i] != "__VIEWSTATE")
								strControls += strKeys[i] + "=" +
									strValues[j] + "\r";
						}

					}
				
					SqlParameter[] param = new SqlParameter[3];
					param[0] = new SqlParameter("@ErrorInfo",SqlDbType.Text);
					param[0].Direction = ParameterDirection.Input;
					param[0].Value = sb.ToString();

					param[1] = new SqlParameter("@ControlsInfo",SqlDbType.Text);
					param[1].Direction = ParameterDirection.Input;
					param[1].Value = strControls.ToString();

					param[2] = new SqlParameter("@Who",SqlDbType.VarChar,50);
					param[2].Direction=ParameterDirection.Input;
					param[2].Value=BizHelp.LanID();

					string conn = SqlHelper.getConnString("PACS","PACS");
					SqlHelper.ExecuteNonQuery(conn,CommandType.StoredProcedure,"INSERT_ERROR_LOG",param);

					MailMessage mm = new MailMessage();
					mm.To = "Veep@somewhere.com";
					mm.From = "Veep@somewhere.com";
					mm.Subject = "PACS Error " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString();
					mm.BodyFormat = MailFormat.Text;
					mm.Body = sb.ToString() + "\r\rControl Information:\r" + strControls;
					mm.Priority = MailPriority.High;
					SmtpMail.SmtpServer="127.0.0.1";
					SmtpMail.Send(mm);
				}
				catch(Exception exp)
				{
					Response.Write("Error on page<br/>");
					Response.Write(exp.Message.ToString() + "<br/>");

				}
			
			
			}
 
Thank you very much. I really do appreciate it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top