Geeks With Blogs

News
Neat Stuff Read all my hurricane entries While you are here, visit the Geeks With Blogs main feed
Advertising
Links Status of the Navy
Channel 9

.NET Hobbyist Programmer Staying Confused in a Busy World

A long time ago, I posted a VB version of this code and thought I would post the C# version since I have gotten several requests.  I have not tested it too extensively yet, but it is working so far.  I had to remove the XML documentation comments for posting here.

I have made some improvements over the VB version, but not significantly.  Eventually I will be posting the whole project structure to CodeProject.

using System;
using System.Text;
using System.Runtime.Serialization;

namespace Kobra.Error
{
  [Serializable]
  public class KobraException : System.Exception
  {
    #region Class Data
    private string appDomainName;
    private string assemblyName;
    private string currentProcessID;
    private string currentThreadID;
    private string currentThreadUser;
    private string machineName;
    private System.DateTime dateTimeUTC;
    private string windowsIdentity;
    // Collection provided to store any extra information associated with the exception
    private System.Collections.Specialized.NameValueCollection additionalInformation;
    // These provide some code simplifications below
    private string newLine = Environment.NewLine;
    private string errorPermissionDenied = "Permission Denied";
    private string errorInfoAccessException = "Information could not be accessed.";
    private System.Type dateTimeType = System.Type.GetType("DateTime");
    private System.Type stringType = System.Type.GetType("String");
    private System.Type collectionType = System.Type.GetType("NameValueCollection");
    #endregion

    #region Constructors
    public KobraException() : base()
    {
      try
      {
        this.assemblyName = System.Reflection.Assembly.GetCallingAssembly().FullName;
      }
      catch (System.Security.SecurityException)
      {
        this.assemblyName = this.errorPermissionDenied;
      }
      catch
      {
        this.assemblyName = this.errorInfoAccessException;
      }
      // Set up our variables and log it
      this.Initialize();
      this.DoLogging(string.Empty);
    }

    public KobraException(string message) : base(message)
    {
      // "message" may be null since the base class handles null by substituting the class name.
      try
      {
        this.assemblyName = System.Reflection.Assembly.GetCallingAssembly().FullName;
      }
      catch (System.Security.SecurityException)
      {
        this.assemblyName = this.errorPermissionDenied;
      }
      catch
      {
        this.assemblyName = this.errorInfoAccessException;
      }
      // Set up our variables and log it
      this.Initialize();
      this.DoLogging(String.Empty);
    }

    public KobraException(string message, System.Exception innerException) : base(message, innerException)
    {
      // "message" may be null since the base class handles null by substituting the class name.
      // "innerException" may be null since there may be cases when this constructor is called, but the
      // inner exception is optional.
      try
      {
        this.assemblyName = System.Reflection.Assembly.GetCallingAssembly().FullName;
      }
      catch (System.Security.SecurityException)
      {
        this.assemblyName = this.errorPermissionDenied;
      }
      catch
      {
        this.assemblyName = this.errorInfoAccessException;
      }
      // Set up our variables and log it
      this.Initialize();
      this.DoLogging(string.Empty);
    }

    protected KobraException(SerializationInfo info, StreamingContext context) : base(info, context)
    {
      // Only test for info being null since that is all that Microsoft tests for.
      // Throw the exception here to get it out as soon as it is discovered.
      if (info == null)
        throw new ArgumentNullException("info");
      // Set up our variables
      this.Initialize();
      // Deserialize our custom properties after Initialize and before logging
      this.dateTimeUTC = info.GetDateTime("kobraDateTime").ToUniversalTime();
      this.appDomainName = info.GetString("kobraAppDomainName");
      this.assemblyName = info.GetString("kobraAssemblyName");
      this.currentProcessID = info.GetString("kobraCurrentProcessID");
      this.currentThreadID = info.GetString("kobraCurrentThreadID");
      this.currentThreadUser = info.GetString("kobraCurrentThreadUser");
      this.machineName = info.GetString("kobraMachineName");
      this.windowsIdentity = info.GetString("kobraWindowsIdentity");
      this.additionalInformation = (System.Collections.Specialized.NameValueCollection)
        (info.GetValue("additionalInformation", this.collectionType));
      this.DoLogging(String.Empty);
    }
    #endregion

    #region Overrides
    [System.Security.Permissions.SecurityPermission(
       System.Security.Permissions.SecurityAction.Demand,
       SerializationFormatter=true)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
      // Serialize our custom properties
      info.AddValue("kobraDateTime", this.dateTimeUTC.ToLocalTime(), this.dateTimeType);
      info.AddValue("kobraAppDomainName", this.appDomainName, this.stringType);
      info.AddValue("kobraAssemblyName", this.assemblyName, this.stringType);
      info.AddValue("kobraCurrentProcessID", this.currentProcessID, this.stringType);
      info.AddValue("kobraCurrentThreadID", this.currentThreadID, this.stringType);
      info.AddValue("kobraCurrentThreadUser", this.currentThreadUser, this.stringType);
      info.AddValue("kobraMachineName", this.machineName, this.stringType);
      info.AddValue("kobraWindowsIdentity", this.windowsIdentity, this.stringType);
      info.AddValue("kobraAdditionalInformation", this.additionalInformation, this.collectionType);
      // Call the base routine
      base.GetObjectData(info, context);
    }

    public override string ToString()
    {
      System.Text.StringBuilder sb = new System.Text.StringBuilder(128);
      // Make sure we get the standard output
      sb.Append(base.ToString());
      // Since the standard output can be nothing, we only add our variables when necessary
      if (sb.Length > 0) 
      {
        // Change this format as required
        sb.Append(this.newLine + this.newLine);
        sb.Append("Local Date Time: " + this.dateTimeUTC.ToLocalTime().ToString() + this.newLine);
        sb.Append("Windows Identity: " + this.windowsIdentity + this.newLine);
        sb.Append("Machine Name: " + this.machineName + this.newLine);
        sb.Append("App Domain Name: " + this.appDomainName + this.newLine);
        sb.Append("Assembly Name: " + this.assemblyName + this.newLine);
        sb.Append("Current Process ID: " + this.currentProcessID + this.newLine);
        sb.Append("Current Thread ID: " + this.currentThreadID + this.newLine);
        sb.Append("Current Thread User: " + this.currentThreadUser + this.newLine);
        // Additional info collection special handling
        if (this.additionalInformation.Count > 0)
        {
          sb.Append("Additional Information: " + this.currentThreadUser + this.newLine);
          foreach (string s in this.additionalInformation.AllKeys)
          {
            sb.Append("   " + s);
            if (this.additionalInformation.Get(s).Length > 0)
            {
              sb.Append(" = " + this.additionalInformation.Get(s));
            }
            sb.Append(this.newLine);
          }
        }
      }
      return sb.ToString();
    }
    #endregion

    #region Private Routines
    private void Initialize()
    {
      this.dateTimeUTC = System.DateTime.UtcNow;
      // **************************************************
      try
      {
        this.appDomainName = System.AppDomain.CurrentDomain.FriendlyName;
      }
      catch (System.Security.SecurityException)
      {
        this.appDomainName = this.errorPermissionDenied;
      }
      catch
      {
        this.appDomainName = this.errorInfoAccessException;
      }
      // **************************************************
      try
      {
        this.currentProcessID = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
      }
      catch (System.Security.SecurityException)
      {
        this.currentProcessID = this.errorPermissionDenied;
      }
      catch
      {
        this.currentProcessID = this.errorInfoAccessException;
      }
      // **************************************************
      try
      {
        this.currentThreadID = AppDomain.GetCurrentThreadId().ToString();
      }
      catch (System.Security.SecurityException)
      {
        this.currentThreadID = this.errorPermissionDenied;
      }
      catch
      {
        this.currentThreadID = this.errorInfoAccessException;
      }
      // **************************************************
      try
      {
        this.currentThreadUser = System.Threading.Thread.CurrentPrincipal.Identity.Name;
      }
      catch (System.Security.SecurityException)
      {
        this.currentThreadUser = this.errorPermissionDenied;
      }
      catch
      {
        this.currentThreadUser = this.errorInfoAccessException;
      }
      // **************************************************
      try
      {
        this.machineName = System.Environment.MachineName;
      }
      catch (System.Security.SecurityException)
      {
        this.machineName = this.errorPermissionDenied;
      }
      catch
      {
        this.machineName = this.errorInfoAccessException;
      }
      // **************************************************
      try
      {
        this.windowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
      }
      catch (System.Security.SecurityException)
      {
        this.windowsIdentity = this.errorPermissionDenied;
      }
      catch
      {
        this.windowsIdentity = this.errorInfoAccessException;
      }
    }

    private void DoLogging(string message)
    {
      // Placeholder for future logging 
    }
    #endregion

    #region Properties
    public System.Collections.Specialized.NameValueCollection AdditionalInformation
    {
      get
      {
        return this.additionalInformation;
      }
      set
      {
        this.additionalInformation = value;
      }
    }

    public string AppDomainName
    {
      get
      {
        return this.appDomainName;
      }
    }

    public string AssemblyName
    {
      get
      {
        return this.assemblyName;
      }
    }

    public string CurrentProcessID
    {
      get
      {
        return this.currentProcessID;
      }
    }

    public string CurrentThreadID
    {
      get
      {
        return this.currentThreadID;
      }
    }

    public string CurrentThreadUser
    {
      get
      {
        return this.currentThreadUser;
      }
    }

    public DateTime DateTime
    {
      get
      {
        return this.dateTimeUTC.ToLocalTime();
      }
    }

    public string MachineName
    {
      get
      {
        return this.machineName;
      }
    }

    public string WindowsIdentityName
    {
      get
      {
        return this.windowsIdentity;
      }
    }
    #endregion
  }
}
Posted on Saturday, July 9, 2005 1:38 PM Programming | Back to top


Comments on this post: Custom Base Exception Class - V3 (C#)

# re: Custom Base Exception Class - V3 (C#)
Requesting Gravatar...
Thanks for the pattern, it gives me a few ideas. Check this page in Firefox, though -- it has some non-wrapping issues.
Left by ew on Nov 30, 2006 9:40 AM

Your comment:
 (will show your gravatar)


Copyright © Mark Treadwell | Powered by: GeeksWithBlogs.net