kamagra how much to take

WebPart Exception / Error Handling

I got asked today what I use for WebPart exception handling / error handling, and I think this may be my first embrassing code post (I think?), with many more to follow, I’m sure. Well, I actually thought it was embrassing, then I read this right before I am posting this:

http://www.codeproject.com/useritems/Errorhandling_in_Webparts.asp

Wow, that’s profound. :)

If it is available and organizationally acceptable I usually go the route of using the Enterprise Library Exception Handling Application Block from MSFT since I think it is great for management and quick configuration changes (and hell, it’s already written), and I really like how all the plumbing is taken care of behind-the-scenes. Since a lot of times organizations prefer custom exception handling classes (for what, I do not know, since you end up re-writing what is already done in the ELEHA) I use an internal class in a generic shared library for exception handling stuff.

This by no means implies that the route I take for exception handling is the right one, in fact, it could probably be improved greatly. Because there are 50,000 blog posts / best standards documents for .NET already on exception handling, hell people do .NET debugging / error handling for a living (that actually sounds like an awful job), I am not really going to dip into the specific of how the code works or profess that this is the best practice available.
My GenericExceptionHandler.cs class is demonstrated at the bottom of this post, I use the route of both creating and writing to a new event source for WebParts to take advantage of the MOSS web event viewer (good for hosting environments), as well I usually write to the executing assembly directory with a custom little text log file with the problems that are encountered (bad for hosting environments).

If you don’t care about the little tidbits on how to use it, since it is pretty straightforward and you can just infer the functionality from the code, just scroll to the bottom, copy and paste, you are ready to rock and roll.
For the rest….

Obviously for some remedial event handling, it doesn’t make utter sense to use this approach, so I just go the standard route of:

  1. catch (Exception exception)
  2. {
  3. output.Write("" + exception.ToString() + "");
  4. continue;
  5. }

In other cases I want to house error in a different medium, in which case I call this class. How do I call this class you ask Batman? There are a couple of different ways, most of them you can infer from the code. Otherwise, let me take the example of our rudimentery exception handling above, which if modified would look something like (or a variation of as you will see when you see the generic exception handler class) this:

  1. catch (Exception exception)
  2. {
  3. GenericExceptionHandler.WriteLine(TraceLevel.Error, "Your Error Text" + exception.ToString(), "YourClassName");
  4. return;
  5. }

You could even set up conditions to test the TraceLevel before doing any work such as writing an event to your event source. This would look like:

  1. if (GenericExceptionHandler.TraceLevel == TraceLevel.Verbose)
  2. {
  3. GenericExceptionHandler.WriteLine(TraceLevel.Verbose, "I am doing something on:" + myString, "YourClassName);
  4. }

You can also create your own exception classes the generic exception handling after an intial custom exception satisfaction is fufilled. Meaning, you could do something like create a new exception handling class for your WebPart that would inherit from the ApplicationException base class so that you could capture non-fatal errors.

  1. using System;
  2.  
  3. namespace arb.Generic.SharedLibrary.exceptionHandling
  4. {
  5. internal class myGreatException : ApplicationException
  6. {
  7. internal myGreatException()
  8. {
  9. }
  10.  
  11. internal myGreatException(string message) : base(message)
  12. {
  13. }
  14.  
  15. internal myGreatException(string message, Exception inner) : base(message, inner)
  16. {
  17. }
  18.  
  19. }
  20. }

Once you have the ApplicationException derived class defined, you can then call the class to bind an exception in your code, and then use the GenericExceptionHandler in order to do whatever you like!

  1. catch (myGreatException exception)
  2. {
  3. GenericExceptionHandler.WriteLine(TraceLevel.Error, "I am doing something" + exception.ToString(), "YourClassName");
  4. }

One of the things that I like to use about this class is also you can write important information as it occurs when you are using it, in something like a method that you call:

  1. public static void myWebPartMethod()
  2. {
  3.  
  4. GenericExceptionHandler.WriteImportantInfoLine("Your Method Is Starting", "YourClassName");
  5.  
  6. }

Or, of course, you can write the same type of thing with verbose information:

  1. public static void myWebPartMethod()
  2. {
  3.  
  4. GenericExceptionHandler.WriteImportantVerboseLine("Your Method Is Ending", "YourClassName");
  5.  
  6. }

Neat! When working with the logging features provided by the class, you should also learn how to start and dispose of the actual logging process. Typically, you start the logging in a constructor or something. Here is an example:

  1. public class testLogging
  2. {
  3. static testLogging()
  4. {
  5. GenericExceptionHandler.StartLogging();
  6.  
  7. }
  8. }

Then in order to teardown logging, you can combine what we have seen this far with the StopLogging() method as provided by the GenericExceptionHandler class. You can write the information out, and then stop the actual logging. This will maintain a good inventory of what the hell is going on with your WebPart.

  1. public static void StopLogging()
  2. {
  3. GenericExceptionHandler.WriteImportantVerboseLine("I want to stop logging por favor", "YourClass");
  4. GenericExceptionHandlerStopLogging();
  5. }

Wow. We have talked a lot about how to use the class, but we haven’t even looked at the class yet. I think I got carried away. The class is below. There are some important .NET concepts that are introduced with it, that I briefly explain below:

Trace class – provides the methods that we require to instigate tracing in the WebPart code.

TraceLevel – used to declare trace message output

TextWriterTraceListener – this is used to writes trace output to some file.

TraceSwitch – This is pretty important. TraceSwitch allows you to control tracing however withouth recompilation, meaning, the TraceSwitch object has a level property that you can set to whatever, from Off to Verbose. It works in a snowball scenario, if you set to a middle tier of tracing, all sub tiers are included in your tracing.

EventLog – Supplies ways to work with the Windows event logs

EventLogEntryType – Enumeration that defines the event log type

That is pretty much all the knowledge you need to be equipped with to understand the class. Feel free to use in your own applications, I don’t really care what you do with it.

//*****************************************************************************
// This code file is part of the Example WebPart Exception Handling
// This file was written by Adam Buenz [WSS MVP] of ARB Security Solutions, LLC
// http://www.sharepointsecurity.com
//
// This is a generic exception handling class file that is
// is meant to allow both writing of events to both the a text
// file in the executing assembly directory as well as creating
// an event source if it doesn’t exist to write errors to there
// as well.
//
// This file and its parts is free for re-distribution, for use in both free
// and commercial applications, however this header must remain intact for legal
// use. This class file is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//*****************************************************************************
//**************************************
// Current Version: 1.0.0.0 (Production)
//**************************************

using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Xml;

namespace arb.Generic.SharedLibrary.exceptionHandling
{
internal class GenericExceptionHandler
{
private static int _keepLogForXDays;
private static TextWriterTraceListener _listener;
private const string _logFieldDateFormat = “yyyyMMdd_HHmmss”;
private static Stream _logFile;
private const string _logFileName = “ExampleLogFile_”;
private static TraceSwitch traceSwitch;

internal static int KeepLogForXDays
{
get
{
return GenericExceptionHandler._keepLogForXDays;
}
set
{
GenericExceptionHandler._keepLogForXDays = value;
}
}

internal static System.Diagnostics.TraceLevel TraceLevel
{
get
{
return GenericExceptionHandler.traceSwitch.Level;
}
set
{
GenericExceptionHandler.traceSwitch.Level = value;
}
}

static GenericExceptionHandler()
{
GenericExceptionHandler.traceSwitch = new TraceSwitch(“SharePointServer”, “Tracing for Your WebPart”);
GenericExceptionHandler._keepLogForXDays = 5;
}

private static void closeLogFile()
{
Trace.Flush();
GenericExceptionHandler._listener.Flush();
GenericExceptionHandler._listener.Close();
Trace.Listeners.Remove(GenericExceptionHandler._listener);
GenericExceptionHandler._logFile.Close();
}

internal static void FlushLogFile()
{
GenericExceptionHandler.closeLogFile();
GenericExceptionHandler.setupLogFile();
GenericExceptionHandler.removeOldLogFiles();
}

private static void removeOldLogFiles()
{
try
{
DateTime curATime = DateTime.Now.AddDays((double)(GenericExceptionHandler._keepLogForXDays * -1));
string[] fArray = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), “LogFile_*.log”);
foreach (string lFile in fArray)
{
try
{
int lLength = lFile.IndexOf(“LogFile_”) + “LogFile_”.Length;
if (lLength > 0)
{
int calcLength = (lFile.Length – lLength) – 4;
string getLength = lFile.Substring(lLength, calcLength);
DateTime repTimeMod = DateTime.ParseExact(getLength, “yyyyMMdd_HHmmss”, CultureInfo.InvariantCulture);
if (repTimeMod.CompareTo(curATime) < 0) { File.Delete(lFile); } } } catch (Exception exception) { GenericExceptionHandler.WriteLine(System.Diagnostics.TraceLevel.Error, “An error has occured in the removeOldLogFiles method(” + lFile + “) : ” + exception.ToString(), “GenericExceptionHandlerClass”); } } } catch (Exception exception) { GenericExceptionHandler.WriteLine(System.Diagnostics.TraceLevel.Error, “An error has occured in the removeOldLogFiles method: ” + exception.ToString(), “GenericExceptionHandlerClass”); } } private static void setupLogFile() { string nPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @”\LogFile_” + DateTime.Now.ToString(“yyyyMMdd_HHmmss”) + “.log”; GenericExceptionHandler._logFile = File.Create(nPath); GenericExceptionHandler._listener = new TextWriterTraceListener(GenericExceptionHandler._logFile); Trace.Listeners.Add(GenericExceptionHandler._listener); } internal static void StartLogging() { GenericExceptionHandler.setupLogFile(); GenericExceptionHandler.removeOldLogFiles(); } internal static void StopLogging() { GenericExceptionHandler.closeLogFile(); } private static void WriteEventLog(System.Diagnostics.TraceLevel TraceLevel, string Message) { EventLogEntryType callMEntry; switch (TraceLevel) { case System.Diagnostics.TraceLevel.Error: callMEntry = EventLogEntryType.Error; break; case System.Diagnostics.TraceLevel.Warning: callMEntry = EventLogEntryType.Warning; break; default: callMEntry = EventLogEntryType.Information; break; } if (!EventLog.SourceExists(“MyWebPart”)) { EventLog.CreateEventSource(“MyWebpart”, “Application”); } EventLog sharepointSignalLog = new EventLog(); sharepointSignalLog.Source = “MyWebPart”; sharepointSignalLog.WriteEntry(Message, callMEntry); } internal static void WriteImportantInfoLine(string Message) { Trace.WriteLine(DateTime.Now.ToString() + ” : ” + Message); GenericExceptionHandler.WriteEventLog(System.Diagnostics.TraceLevel.Info, Message); } internal static void WriteImportantInfoLine(string Message, string Category) { Trace.WriteLine(DateTime.Now.ToString() + ” : ” + Message, Category); GenericExceptionHandler.WriteEventLog(System.Diagnostics.TraceLevel.Info, Category + “: ” + Message); } internal static void WriteImportantVerboseLine(string Message) { Trace.WriteLine(DateTime.Now.ToString() + ” : ” + Message); } internal static void WriteImportantVerboseLine(string Message, string Category) { Trace.WriteLine(DateTime.Now.ToString() + ” : ” + Message, Category); } internal static void WriteLine(System.Diagnostics.TraceLevel TraceLevel, string Message) { GenericExceptionHandler.WriteLine(DateTime.Now, TraceLevel, Message); } internal static void WriteLine(DateTime time, System.Diagnostics.TraceLevel TraceLevel, string Message) { int nLevel = (int)TraceLevel; if ((nLevel <= 2) || (((System.Diagnostics.TraceLevel)nLevel) <= GenericExceptionHandler.traceSwitch.Level)) { Trace.WriteLine(time.ToString() + ” : ” + Message); } if ((nLevel != 4) && (((System.Diagnostics.TraceLevel)nLevel) <= GenericExceptionHandler.traceSwitch.Level)) { GenericExceptionHandler.WriteEventLog(TraceLevel, Message); } } internal static void WriteLine(System.Diagnostics.TraceLevel TraceLevel, string Message, string Category) { GenericExceptionHandler.WriteLine(DateTime.Now, TraceLevel, Message, Category); } internal static void WriteLine(DateTime time, System.Diagnostics.TraceLevel TraceLevel, string Message, string Category) { int nLevel = (int)TraceLevel; if ((nLevel <= 2) || (((System.Diagnostics.TraceLevel)nLevel) <= GenericExceptionHandler.traceSwitch.Level)) { Trace.WriteLine(time.ToString() + ” : ” + Message, Category); } if ((nLevel != 4) && (((System.Diagnostics.TraceLevel)nLevel) <= GenericExceptionHandler.traceSwitch.Level)) { GenericExceptionHandler.WriteEventLog(TraceLevel, Category + “: ” + Message); } } } }[/csharp] So that is my exception handling class. Again, I am not saying it is a right or wrong one, its just one I use, and after I saw that post on CodeProject, yeesh. :) I would be interested to hear about what others use for their WebPart exception handling. Maybe someone would want to work on a best practices document with me?

Share

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>