I think when they talk about a layer boundary they are talking about places where the security sensitivity changes or the call is coming from outside your scope of influence. The main concern is that security sensitive information does not leak out of your application in exceptions. So for example if an error is for a database connection the exception message might be "Unable to access database on serve ServerName". If this kind of exception gets out of your application it gives a hacker the name of you database server which is a bad thing.
These security boundaries are normally at the process boundary. On server applications that would mean any public web services, remote procedure calls or that kind of thing. Also in Web and Win-Forms applications there are global error handlers that handle any un-handled exceptions. I would not expect an in-process dll to include such a boundary.
Once you have identified each of boundary entry points you should use a try catch and then pass the exception to the Microsoft Exception Handling Block. The Exception Handling block allows logging of exceptions and allows you to decide which exception details get thrown to the user. This helps to ensure that security sensitive information does not leak out of your application in exception stack traces.
Global Exception Handler in WinForms:
In WinForms there are two global exception handlers these are defined as events that fire whenever there is an unhandled exception. The best thing to do is to bind to these in your main() function before the Application.Run statement like this:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}
Using the exception application block you would then handle these events like this:
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
// ...
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
bool rethrow = ExceptionPolicy.HandleException(e.Exception, "Thread Policy");
if (rethrow)
{
Application.Exit();
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
ExceptionPolicy.HandleException((Exception)e.ExceptionObject, "App Policy");
// This event always exits the
// application so there is no point in looking at
// HanleException result.
}
The difference between these two events is that the ThreadException event only handles events that are created by WinForm's threads. It will also allow the application to continue if you do not rethrow the exception in the event. The UnhandledException event will catch all exceptions in the process but does not allow you to continue so it is only good for logging.
Finally to get the MS Exception block to work you need to add some configuration to the App.Config file like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=2.0.0.0, Culture=neutral, PublicKeyToken=e99c4c62013e92da"/>
</configSections>
<exceptionHandling>
<exceptionPolicies>
<add name="App Policy">
<exceptionTypes>
<add name="App Exception" type="System.Exception, mscorlib" postHandlingAction="None" />
</exceptionTypes>
</add>
<add name="Thread Policy">
<exceptionTypes>
<add name="App Exception" type="System.Exception, mscorlib" postHandlingAction="None" />
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
</configuration>
You would normally do a far more sophisticated exception policy than this, but I won't go into that here.
Global Exception Handler in ASP.Net
In ASP.Net things are a little easier. All you need to do is implement the Application_Error event in the Global.asax file. To get the last error call Server.GetLastError() and to continue without rethrowing the exception call Server.ClearError(). So your code would look something like this:
<%@ Application Language="C#" %>
<script runat="server">
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
bool rethrow = ExceptionPolicy.HandleException(ex, "App Exception");
if (!rethrow)
{
Server.ClearError();
}
Response.StatusCode = 500;
}
</script>