Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 575
  • Last Modified:

problem with global error catching

i am trying to set up a error page to catch all server errors.  however when ever i call a method of Exception i get: "Object reference not set to an instance of an object."

example( error line 10 ):
     1     System.Exception err = Server.GetLastError();
     2     StringBuilder sb = new StringBuilder();
            .
            .
            .
     10   sb.Append( "<br><i>Error Msg: </i>" + err.Message);

what am i missing?
0
meyerc74
Asked:
meyerc74
  • 17
  • 11
  • 6
  • +1
1 Solution
 
SirCalebCommented:
Try using Server.GetLastError.GetBaseException instead.
0
 
mmarinovCommented:
are you sure that you don't use somewhere Server.ClearError()?
first, and second how do you go to these lines? i mean is it possible to go to this page whitout error? or to call for example Page_Load twice and in the end of the first call you clear the errors ?

B..M
0
 
meyerc74Author Commented:
i tried
     System.Exception err = Server.GetLastError().GetBaseException();

now i get the same error but on the declaration line this time

there is no Server.ClearError() anywhere in the site.

these lines are the lines of void reportError() which is called from page_load().

you can get to the page if you call it directly (http://www.mysite.com/errorPage.aspx) but that is not the case.  the page is in development and i got to it off of an error i created on a page
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
mmarinovCommented:
how do you go to the errorPage.aspx? because if you don't throw the exception but catch it  and do nothing after that Server.GetlastError() will return null

B..M
0
 
SirCalebCommented:
Are you trying to do this in the page that the error is redirected to by the web.config?  If so, it automatically clears the error ... you have to trap in the global.asax FIRST ...

  Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
    If Not Server.GetLastError.GetBaseException.GetType Is Type.GetType("System.IO.FileNotFoundException") Then
      If Server.GetLastError.GetBaseException.Message.IndexOf("viewstate") = -1 Then
        LogException(Server.GetLastError.GetBaseException, "Unhandled Exception trapped in Global.asax")
      End If
    End If
  End Sub

I have a custom routine called "LogException" that I use to write exceptions into a database table.
0
 
meyerc74Author Commented:
yes....i am trying to do this on the page that is called by web.config.....the implication above is that i need to catch an error on every page(if any).....i have no global.asax page....i do not use visual studio or any other visual complier, just a text editor
0
 
mmarinovCommented:
how do you exactly catch the error on each page? what code do you use ?

B..M
0
 
meyerc74Author Commented:
i don't....my inital understanding of the custom errors functionality was it was a catch all at the application level...and my custom error page would do what i wanted it to do...similar to the cferror tag in cold fusion.....i am begining to think this impression was inacurate
0
 
meyerc74Author Commented:
however... i am testing this by creating an error....i removed the { on my page_load function.  how can that be caught?
0
 
SirCalebCommented:
What is your goal with the custom error page?  To log/record the error in addition to a more "friendly" screen?

You can trap the error on the page-level if you want:

  Private Sub Page_Error(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Error
      If Server.GetLastError.GetBaseException.Message.IndexOf("viewstate") = -1 Then
        LogException(Server.GetLastError.GetBaseException)
      End If
  End Sub

Put it into a session object, whatever.
0
 
meyerc74Author Commented:
i want the custom error page to display some type of message.. and the email me the error details.

i tried adding:
      public void Page_Error(object sender,EventArgs e){
            Exception pgErr = Server.GetLastError().GetBaseException();
            string err = "<b>Error Caught in Page_Error event</b><hr><br>" + "<br><b>Error in: </b>" + Request.Url.ToString() +      "<br><b>Error Message: </b>" + pgErr.Message.ToString();
                        err += "<br><b>Stack Trace:</b><br>" + pgErr.StackTrace.ToString();
                        
            Response.Write(err.ToString());
            Server.ClearError();
            Response.Write( "<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" width=\"98%\" align=\"center\">\n\t<tr>\n\t\t<td class=\"headers\" align=\"center\">\n\t\t\t" );
            Response.Write( "Something has gone arwy.  An error report has been generated and sent to developers.<br>  We Apoligize for any inconvience.\n\t\t</td>\n\t</tr>\n</table>");
      }

but when custom errors is off...it shows the error
when custom errors is on( and server.clearError() is comminted out ) i still get the orginal error
0
 
SirCalebCommented:
Ok, do this ... turn custom errors back on ...

Put this into the PAGE that is throwing the exception ...

  Private Sub Page_Error(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Error
      Session("LastException") = Server.GetLastError.GetBaseException
  End Sub

Now, in your custom error page, change the following line:

Exception pgErr = Server.GetLastError().GetBaseException();

to

Exception pgErr = Session("LastException");
0
 
meyerc74Author Commented:
good idea.....but same error......here is my test page:

<script language="C#" runat="server">
      string gs_status = "Pending,In Progress";
      
      void page_load(){
            string i = "" /* no ; - this is the error */
      }
      
      public void Page_Error(object sender,EventArgs e){
            Session["lastException"] = Server.GetLastError().GetBaseException();
      }
</script>

here is my error.aspx page:

<script language="C#" runat="server">
      void page_load(){
            reportError();
      }
      
      void reportError(){
            System.Exception err = new System.Exception( Session["lastException"].ToString() );Response.Write( "-" + err.Source + "-" );
Response.End();

</script>

the error page gives me " Object reference not set to an instance of an object. " for the err declartion line

i also tired System.Exception err = Session["lastException"]; but that sated cannot inplicitly convert object to exception

0
 
SirCalebCommented:
Add an asp:label to your errorPage aspx and set the text property = Session["lastException"].ToString() ... it looks like the baseException may not be there ... let's try this first and see if it's even getting populated.
0
 
gregoryyoungCommented:
hmmmm.......

use a static page for your error page since you probably dont want to display the stack dump to the user ...

then ....

take a look at this ...

somewhere in your app (application start might be a good place but there are others) do this ....

ExceptionHandler handler = new ExceptionHandler();
Application.ThreadException += new ThreadExceptionEventHandler(handler.Application_ThreadException);


then put this class in your project (modify it to your needs)
using System;
using System.Threading;
using System.Windows.Forms;
using System.Web;
using System.Web.SessionState;
using System.Web.Mail;
using System.Diagnostics ;
namespace ExceptionHandling{
      /// <summary>
      /// Summary description for ExceptionHandler.
      /// </summary>
      internal class ExceptionHandler {
            ///
            /// Handles the thread exception.
            ///
            public void Application_ThreadException(
                  object sender, ThreadExceptionEventArgs e) {
                  try {
                              // write to event log ?                              MailMessage mail = new MailMessage();
                              mail.From = "";
                              mail.To = "";
                              mail.Subject = "" + e.Exception.Message;
                              string Message = e.Exception.Message + "\n\n" + e.Exception.StackTrace ;
                              mail.Body = Message.Replace("\n", "<br>");
                              mail.BodyFormat = MailFormat.Html;
                              SmtpMail.SmtpServer = "";
                              SmtpMail.Send(mail);
                        }
                        catch (Exception Ex) {
                              //aint much we can do here
                              System.Diagnostics.Trace.WriteLine(Ex.ToString());
                        }
                  }
            }
      } // End ThreadExceptionHandler
}


0
 
meyerc74Author Commented:
no  correct does not appear to be there
0
 
meyerc74Author Commented:
to be more specific....response to SirCaleb - the same error gets returned "Object reference not set to an instance of an object."
0
 
gregoryyoungCommented:
btw the nice thing about the code I posted is that once you come up with your nifty classes for handling errors you can use the same methodology in fors applications ;)

i might change it up a little bit so it wors like a singleton though ...

in the ExceptionHandler class

static ExceptionHandler Instance ;
static void hookEvents() {
    if(Instance != null) {
         Instance = new ExceptionHandler()
         Application.ThreadException += new ThreadExceptionEventHandler(Instance.Application_ThreadException);

    }
}

thus its encapsulated.
0
 
meyerc74Author Commented:
as far as this class goes won't i need to instanciate it for every exception?  or will it work as a catch all, like i need it to?
0
 
gregoryyoungCommented:
yes you instantiate that once then it is setup for your whole application.

Greg
0
 
meyerc74Author Commented:
ok...great......now how do i do that?.....i do not use visual studio for writing web stuff ( although i guess this would be an argument for using it )....i simply use a text editor.....i have created and compiled the class...copied the dll into the root bin folder....what else do i need to do?
0
 
SirCalebCommented:
Visual Studio .NET will pay for itself in one day in gained productivity ... the intellisense alone is worth it!
0
 
gregoryyoungCommented:
for asp.net ... go into your global.asax and on application start call HookEvents ... if they are already hooked it will do nothing.
0
 
meyerc74Author Commented:
ok....the class is not going to work....i do not have a global.asax as this is not a web application written in visual studio........i am begining to realize this is not going to work the way i want it to
0
 
gregoryyoungCommented:
thats fine you can hook it anywhere.

when your app starts call HookEvents
0
 
meyerc74Author Commented:
ok...i think we are on to something here.....i threw application_start into my header.aspx file and it seems to be working.....my only problem now is how do i get the new class recognized?
0
 
gregoryyoungCommented:
recognized ?

you mean how do you get it to work ?

did you put the HandleEvents method in the class ?

just call ExceptionHandler.HookEvents()
0
 
meyerc74Author Commented:
i did that....it errors "The type or namespace name 'ExceptionHandler' could not be found"....i built the class in visual studio then copied the dll and cs files into the bin dir of my site.....what am i missing?
0
 
gregoryyoungCommented:
ah you most likely need to include the .dll and put in a using statement at the top of your page for whatever namespace you decided to use.
0
 
meyerc74Author Commented:
sorry....new to this aspect of asp.net......i tried the using directive but it errored .....could i ask you the syntax?
0
 
gregoryyoungCommented:
using System.Data.SqlClient;
is an example ...

Or you can refer to it in full ...

System.Data.SqlClient.SqlConnection foo;
0
 
meyerc74Author Commented:
with ExceptionHandling.ExceptionHandler handler = new  ExceptionHandling.ExceptionHandler();

i get

'ExceptionHandling.ExceptionHandler' is inaccessible due to its protection level

0
 
gregoryyoungCommented:
it doesnt = a new one...

just call ExceptionHandling.ExceptionHandler.HookEvents();
0
 
meyerc74Author Commented:
same thing

'ExceptionHandling.ExceptionHandler' is inaccessible due to its protection level
0
 
gregoryyoungCommented:
did you make it a public class in your .dll ?
0
 
meyerc74Author Commented:
yes...but i forgot to rebuild once i did that.....thanks!!!!
0
 
gregoryyoungCommented:
heh dont you hate it when you do stuff like that ? I spent an hour trying to find a problem the other day because I didnt copy a .dll after I built.

Hope everything works for ya ...

remember that once you get your classes going there you can share them with your forms apps ...
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 17
  • 11
  • 6
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now