SSW .NET Toolkit > User Guide
Handling and storing exceptions in a central location
Key Features of LadyLog
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.
Figure: This is good because it will automatically submit the stack trace and email the developer so you will get a response when fixed
- 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:
- Product Name which caused the exception
- Product version
- Internal Notes (.NET Framework version,
etc.)
- User email
- User Notes
- User's Operating System
- Error Message
- 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:
- Reference the SSW.Framework.ExceptionManagement DLL in your project.
- 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" ?>
<configuration>
<configSections>
<section
name="applicationConfigurationManagement"
type="Microsoft.ApplicationBlocks.ConfigurationManagement.
ConfigurationManagerSectionHandler,
SSW.Framework.Configuration" />
<section
name="FileSettings"
type="
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
-
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;
[STAThread]
static void Main(string[] args )
{
Application.ThreadException +=
new System.Threading.
ThreadExceptionEventHandler(ExceptionManager.ThreadExceptionHandler);
AppDomain.CurrentDomain.UnhandledException
+= 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)
{
Microsoft.ApplicationBlocks.ExceptionManagement.
ExceptionManager.Publish(Server.GetLastError());
}
-
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:
- ExceptionManager.ApplicationName
- System.Windows.Forms.Application.ProductName
- AppDomain.CurrentDomain.BaseDirectory
If theres a file named with the same name as the BaseDirectory in the directory, then that will be used.
- The assembly file name of the Assembly.GetEntryAssembly()
- The assembly file name of the Assembly.GetCallingAssembly()
- The command the application was stated with:
e.g. MyApp.exe arg1 arg2
MyApp?would be used as the application name
- The assembly file name of the Assembly.GetExecutingAssembly()
- assembly.FullName
The following code will allow you to specify the application name used by Exception Reporting Service
-
ExceptionManager.ApplicationName = strProductName
ExceptionManager.ApplicationVersion = strProductVersion
-
- 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:
-
try
{
...
}
catch (Exception ex) // catching all Exceptions
{
...
}
-
Figure: Try to catch specific exceptions
- (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>" />
-
<FileSettings>
<appSettings>
... other entries
<add key="EMAIL:nunit-gui" value="johnliu@s*w.com.au" />
</appSettings>
</FileSettings>
-
Figure: Do you want to be notified if an error in your product is submitted
in the web service?
- 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