⚠️ This page has been archived

✅ New page with updated info: ssw.com.au/products

SSW .NET Toolkit > User Guide

DOT NET Tool kit - Develop Applications More Efficiently with the SSW .NET Toolkit

Handling and storing exceptions in a central location

Key Features of LadyLog

  1. Provides a slick way for your users to report bugs in your applications and solves the rule Do you include Exception Logging and Handling? so you get no more nasty windows like

    Figure: This is bad a user should never see this

    Instead of the above windows when the application crashes, the SSW Exception Reporter kicks-in and provides a way to submit this exception back to home base where it can be investigates and resolved in future versions of your product. This is somehow similar to the way windows reports a bug when it crashes, as it sometimes does.

    Exception Reporter
    Figure: This is good because it will automatically submit the stack trace and email the developer so you will get a response when fixed

  2. SSW Exception Reporting Services provides a web-based system to view bug reports submitted by your users

    Clicking on view on that page will show a comprehensive details about the bug report, including:

    1. Product Name which caused the exception
    2. Product version
    3. Internal Notes (.NET Framework version, etc.)
    4. User email
    5. User Notes
    6. User's Operating System
    7. Error Message
    8. Full Stacktrace

How do I use the LadyLog in my application?

You can implement the LadyLog in your applications by following the steps listed below. Any exceptions you report will be sent to the SSW Exception Database.

Please note that you will only be able to view exceptions reported with your own Client ID.
You can get your Client ID and see all your exceptions using the Exception Summary page

Figure: Getting your Client ID

In order to implement the SSW Configuration Block, follow these simple steps:

  1. Reference the SSW.Framework.ExceptionManagement DLL in your project.
  2. Modify the App.Config file for your application (or Web.Config), you will need to have some additional lines
    <?xml version="1.0" encoding="utf-8" ?>
           SSW.Framework.Configuration" />
    SSW.Framework.Configuration.DictionarySectionHandlerWriter, SSW.Framework.Configuration" /> <section name="exceptionManagement" type="
    Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManagerSectionHandler, SSW.Framework.ExceptionManagement" />
    </configSections> <exceptionManagement> <!-- mode="on" turn it 'off' if you don't want it. assembly type don't change these. exclude = "*" this will use this current publisher to exclude any type of exception include = "*" this will force the publisher to include any type of exception, IMPORTANT: include OVERWRITES exclude value, so if you had: exclude="System.Exception" include="System.Exception" System.Exception will still be included. A plus (+) can be used to indicate that you want to include this type and all the inherited types: Exclude="+System.ApplicationException" will exclude any of the Exceptions inheriting or is an ApplicationException for the current publisher IMPORTANT: For these types in both Include and Exclude tags, you MUST use the correct entire long name. i.e. "System.Exception" is correct. "Exception" is NOT correct. ................................................................................... submit = "true" default value for whether the user will submit the exception or not interactive = "true" default value for whether the process will show a dialog, a windows service or asp.net, for example, would not show a dialog and hence should be "false". Note that Environment.UserInteractive must be true or the dialog won't be shown anyway. clientid = "ssw" specify the client that the error is logged for, for example, if we also sold service for CPF to monitor their bugs then we'd use CPF instead of ssw. server1 = "mail.ssw.com.au" server2 = "joey" because of the way our ISA (chook) is configured, externally, the web service publisher must locate "mail.ssw.com.au" whereas internally, it must locate "joey". The settings contains information for the publisher to locate the webservice webservers. jliu 08/2003 --> <publisher mode="on" assembly="SSW.Framework.ExceptionManagement" type="SSW.Framework.ExceptionManagement.Publishers.WebServicePublisher" exclude="" include="" submit="true" interactive="true" clientid="TEST" useremail="" server1="webservices.internal.ssw.com.au" server2="tuna" /> <!-- mode = "off" turn off the default publisher, which will try to log to the user's event log/viewer you should look into the event viewer when developing to see if there's any internal Exception Management exceptions - this usually indicates that you have some errors in your configuration file. --> <publisher mode="off" assembly="SSW.Framework.ExceptionManagement" type="Microsoft.ApplicationBlocks.ExceptionManagement.DefaultPublisher" include="*" /> <!-- This is the EMail publisher, you need to configure: SmtpServer = "wolf" or "mail.ssw.com.au" To, CC, From = email addresses Remember to turn mode="on" if you want to use it. --> <publisher mode="off" assembly="SSW.Framework.ExceptionManagement" type="SSW.Framework.ExceptionManagement.Publishers.EmailExceptionPublisher" SmtpServer="mail.ssw.com.au" To="PeterHuang@s*w.com.au" Cc="" From="Info@s*w.com.au" /> <!-- This is the file publisher, you need to configure: fileName = "filename.log" (in the current application directory) You can also use absolute paths. Remember to turn mode="on" if you want to use it. --> <publisher mode="off" assembly="SSW.Framework.ExceptionManagement" type="SSW.Framework.ExceptionManagement.Publishers.FilePublisher" fileName="Exceptions.log" /> </exceptionManagement> </configuration>
    Figure: Modifying the App.Config file for your application
  3. Configure your application to handle exceptions
    • For windows applications , we will need to add one line of code to catch thread exceptions .

      A while ago, I had explained that when you are in a Windows Application, you should use Application.ThreadException to handle uncaught exceptions. While this still remains true, theres some additional notes you need to be aware of.

      Application.ThreadException only handles uncaught exceptions within the Application thread. That is, it will only handle exceptions coming from the forms, etc - inside the light green section. Exceptions thrown outside of the application thread, for example in the yellow section , will not raise an Application.ThreadException event.

      You must still catch these exceptions using the AppDomains UnhandledException event. Shown in light blue .

      // C#
      Using Microsoft.ApplicationBlocks.ExceptionManagement;
      static void Main(string[] args )
       Application.ThreadException +=
         new System.Threading.
         += new UnhandledExceptionEventHandler(ExceptionManager.UnhandledExceptionHandler);
         if( args != null && args.Length == 1 &&
      args[0].ToLower() =="/silent" ) { CPFIntegratorLib.Integrator integrator = CPFIntegratorLib.Integrator.GetInstance(); integrator.Process(); return; }
      Application.Run(new frmMain()); } ' VB.NET Imports Microsoft.ApplicationBlocks.ExceptionManagement Public Shared Sub Main() AddHandler Application.ThreadException, AddressOf ExceptionManager.ThreadExceptionHandler ... End Sub
      Figure: Exception Management
    • For web applications , we will need to add one line of code to your Global.asax file:
      protected void Application_Error(Object sender, EventArgs e)
      Figure: Global.asax
    • For Outlook/VS.NET Plug-ins , because these are hosted by another application, you need to be aware that Exception Reporting Service will attempt to discover the name of the application in the following order:
      1. ExceptionManager.ApplicationName
      2. System.Windows.Forms.Application.ProductName
      3. AppDomain.CurrentDomain.BaseDirectory
        If theres a file named with the same name as the BaseDirectory in the directory, then that will be used.
      4. The assembly file name of the Assembly.GetEntryAssembly()
      5. The assembly file name of the Assembly.GetCallingAssembly()
      6. The command the application was stated with:
        e.g. MyApp.exe arg1 arg2
        MyApp?would be used as the application name
      7. The assembly file name of the Assembly.GetExecutingAssembly()
      8. assembly.FullName

      The following code will allow you to specify the application name used by Exception Reporting Service

      ExceptionManager.ApplicationName = strProductName	
      ExceptionManager.ApplicationVersion = strProductVersion
  4. Try not to use code like this - they will hide the exceptions from you. Only do this if you know what you are doing. Catch specific exceptions that you ARE expecting, rather than catch any exception:
        catch (Exception ex) // catching all Exceptions
    Figure: Try to catch specific exceptions
  5. (Optional) If you want to be notified when an error is submitted about your product in the web service, you need to modify the Email.Config file for the web service. In our case this belongs in:  \\tuna\c$\Inetpub\wwwroot\ExceptionReportingService\Email.config and add the following key:

    <add key="EMAIL:<your product name>" value="<your email address>" />
              ... other entries
              <add key="EMAIL:nunit-gui" value="johnliu@s*w.com.au" />
    Figure: Do you want to be notified if an error in your product is submitted in the web service?
  6. See the Exception Summary page:

Upcoming Features

  • Elmah support
  • Minimal size download
  • Add support in TFS Smashing Barrier
  • Demo video
  • Enterprise Library support
  • Silverlight support ?Capture unhandled Silverlight exceptions
  • Convert to WPF and offer a few Skins

Note that our exception management block is part of our Rules to Better .NET Projects