    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Maintaining Context for Exceptions (Alternative)</title>
        <link>https://members.accu.org/index.php/articles/1253</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 15, #6 - Dec 2003</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c105/">156</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-105/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+105/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Maintaining Context for Exceptions (Alternative)</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 December 2003 13:16:02 +00:00 or Wed, 03 December 2003 13:16:02 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>At ACCU 2002 Andrei Alexandrescu talked about storing contextual
information in the event of an exception being thrown. The
individual elements of context mirror the unwinding of the stack
and the progress from lower level code to wherever the exception
finally stops and is communicated to the user.</p>
<p>It is at the lower level that things (normally) go wrong because
that's where the work is done. Unfortunately at that level we are
in often the worst position to compose a meaningful error message.
The low level code lacks knowledge of the overall intent of the
code - this is because we needed to break things down and wanted
reuse!</p>
<p>We are interested in what went wrong and what we were trying to
do at the time. At the point of the error we know what went wrong,
and as we unwind the call stack we move through the levels of
detail about what was being attempted.</p>
<p>If, when an error occurs we use an exception to report the
specific problem and as that exception unwinds the stack we record
the context, we can get a full report on what went wrong. This is
helpful to the user and anyone supporting the product (who are
helpful to the user).</p>
<p>Rob Hughes' article in the August CVu explained a system that he
had developed and used in his projects. At Chersoft we were also
inspired by Andrei to create a parallel system which we have
successfully used in commercial 'shrink wrap' software.</p>
<p>In this article I'll outline the similarities and differences
between our approaches, some extra bits we do and the evolution of
our system - some of which has come from looking at Rob's August
piece. It might be worth getting hold of it and reading it before
tackling this one.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e34" id="d0e34"></a>Similarities
and Differences</h2>
</div>
<p>Both systems use a class for each piece of context and macros to
put instances of it onto the stack (singleton pattern). We have not
needed to do a 'thread specific singleton' though we considered
it.</p>
<p>We have both 'user' and 'technical' messages - we can put all
sorts of useful stuff in the technical messages that might scare
the users but would be handy for programmers supporting a
product.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e41" id=
"d0e41"></a>std::uncaught_exception()</h2>
</div>
<p>Rob reports that <tt class=
"methodname">std::uncaught_exception()</tt> always returns
<tt class="constant">false</tt> with Borland C++ builder. Same for
VC++ 6.0 - in the Dinkum STL you can read code a bit like:</p>
<pre class="programlisting">
bool std::uncaught_exception() {
  return false;
}
</pre>
<p>It doesn't even try! We tried writing our own but it was
desperate and we retreated.</p>
<p>A properly service packed VC++.NET works correctly. We develop
our code to compile and run using both VC++ 6.0 and VC++.NET, so we
have a workaround - our own exception base class. CExceptionBase,
as it's known, increments a static int on construction and
decrements it on destruction.</p>
<pre class="programlisting">
static bool CExceptionBase::Uncaught() {
  #if _MSC_VER &gt;= 1300
  return std::uncaught_exception();
  #else
  return s_nInstances &gt; 0;
  #endif
}
</pre>
<p>The context class uses the above static method to determine
whether an exception is active. As long as classes derived from
<tt class="classname">CExceptionBase</tt> are just thrown as
exceptions it is fine.</p>
<p>We derive various exceptions from this base and have a dialog
which reports on the exception and the context stack.</p>
<p>So we are ok if we throw our own exceptions.</p>
<p>But we are at risk from STL exceptions and platform
specifically:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Various MFC exceptions</p>
</li>
<li>
<p>COM exceptions</p>
</li>
<li>
<p>Win32 structured exception handling exceptions!</p>
</li>
</ul>
</div>
<p>So in various ways we convert these exceptions into our own.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e83" id="d0e83"></a>Exception
Translation</h2>
</div>
<pre class="programlisting">
catch(CFileException * pEx) {
  throw CExceptionMFC_File(pEx);
}
catch(CArchiveException * pEx) {
  throw CExceptionMFC_Archive(pEx);
}
catch(CException * pEx) {
  throw CExceptionMFC(pEx);
}
catch(std::exception&amp; ex) {
  throw CExceptionSTL(ex);
}
catch(const _com_error&amp; ex) {
  throw CExceptionCOM(ex);
}
catch(csx::CExceptionBase&amp;) {
  throw;
}
</pre>
<p>This deals with the nasty way MFC news exceptions and has them
deleted and so on. The information contained in the exceptions is
sucked out, put in one of ours and thrown.</p>
<p>We put this in a macro and called it <tt class=
"function">CATCH_RETHROW</tt>. The translation is handy, we can
still use our dialog:</p>
<pre class="programlisting">
try {
  try {
    CONTEXT(&quot;Doing the work!&quot;);
    // do the work involving lots of
    // method calls etc..
  }
  CATCH_RETHROW;
}
catch(const CExceptionBase&amp; ex) {
  CexceptionDlg dlg(ex, CexceptionContextStack
           ::Instance().GetAndResetContext());
  dlg.DoModal();
}
</pre>
<p>Wonderful! But on a compiler without a proper <tt class=
"methodname">std::uncaught_exception</tt> we miss out on an awful
lot of contexts. We only get context information after <tt class=
"function">CATCH_RETHROW</tt> has been done. We need more of
them!</p>
<p><tt class="function">try</tt>..<tt class="function">catch</tt>
blocks are costly, the compiler needs to put up all sorts of
scaffolding to support their operation. We don't want every
function to have one.</p>
<p>As an aside... at a previous company I worked an a system where
(nearly) every function was something like...</p>
<pre class="programlisting">
void foo() {
  try {
    // work
  }
  catch(Cexception&amp; ex) {
    ex.AddMessage(&quot;Bit of context&quot;);
    throw ex;
  }
}
</pre>
<p>It was more complicated and macros were used. The code was
slightly obscured, larger and slower. On the other hand it could
produce good errors and there was a consistent application wide
error handling scheme.</p>
<p>Getting back to the present...</p>
<p>We tend to put the extra <tt class="function">CATCH_RETHROW</tt>
blocks around where we think an exception might emerge - looking at
the list of exceptions that's not too hard to do. When we switch to
the VC++ .NET compiler completely the problem goes away (and it is
a better compiler).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e125" id="d0e125"></a>Key
difference: push..pop or just push</h2>
</div>
<p>Rob's solution has a context class that pushes information onto
a stack on construction and removes it if an exception is not
active. Our context class pushes on destruction. If an exception
were thrown during our pushing there would be two exceptions on the
go at once and the application would terminate because that's not
allowed.</p>
<p>Rob's code is exception safe as the STL <tt class=
"classname">deque</tt> guarantees that <tt class=
"methodname">pop_back()</tt> will not throw.</p>
<p>We take a risk that on Windows memory allocation doesn't tend to
fail - it just takes a very long time when memory is low. By this
stage everything has gone horribly wrong anyway.</p>
<p>In return for taking the risk we gain quite a lot of efficiency
because the context class does very little, excepting the
exceptional case.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e142" id="d0e142"></a>Win32 SEH
Translation</h2>
</div>
<p>We convert Win32 structured exceptions like 'Access Violation'
into C++ exceptions derived from our exception base class. This is
done by hooking in using the function <tt class=
"function">_set_se_translator</tt>.</p>
<p>It's OS specific so I'll not go into detail. Googling on the
function name above will help anybody interested. It means we get a
bit more information if a 'crash' occurs.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e152" id="d0e152"></a>How our
system has evolved: Clearing the stack</h2>
</div>
<p>If the stack has context information left over from a previous
exception on it when an exception is thrown the user could be
exposed to two sets of context, which is confusing.</p>
<p>Our first stab at dealing with this potential hazard was for the
method which returned the context information to return a copy of
the stack and then clear the stack.</p>
<pre class="programlisting">
const CContextInformation
CExceptionContextStack::GetAndResetContext();
</pre>
<p>But, before long another method had turned up:</p>
<pre class="programlisting">
const CContextInformation&amp; Context() const
</pre>
<p>It was handy to peek at the stack in order to write it out to a
debug window.</p>
<p>The stack could be cleared automatically in the context class
constructor - if there is not an exception on the go the stack can
be cleared.</p>
<pre class="programlisting">
CContext::CContext(..) :
m_bExAtStart(std::uncaught_exception()) {
  if(m_bExAtStart)
    ClearStack();
}
</pre>
<p>It adds to the overhead of using context of course. It depends
on the application whether or not this is a concern.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e173" id="d0e173"></a>Tightening up
the context class</h2>
</div>
<p>Originally we did not have a flag in the context class that
recorded whether or not there was an active exception on
construction.</p>
<pre class="programlisting">
CContextString::~CContextString() {
  if(!m_bExceptionAtStart &amp;&amp;
                  ExceptionBase::Uncaught()) {
    PushContext();
  }
}
</pre>
<p>This prevents the case where a context macro is encountered in
code during the unwinding process (perhaps in a library call). This
potentially results in a confusing extra message on the context
stack.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e182" id="d0e182"></a>The Hard
Bit</h2>
</div>
<p>Now that the technical bits are out of the way the system must
be used, you still need to write appropriate, useful messages. What
is the audience for them? The more wide ranging the worse it
is.</p>
<p>You need enough information for the more able users to sort
things out themselves, but error messages can scare less expert
users who fear for their lives and freedom at talk of 'fatal'
errors and 'illegal' operations.</p>
<p>We've found that it is worth provoking a few errors to see what
messages emerge, by changing the code, deleting files or whatever
it takes. We modify the results by changing text, adding more
context macros and so on.</p>
<p>Redundant or inappropriate information is almost as bad as too
little. An agreed policy helps.</p>
<p>One case we've seen is 'file not found', in most situations you
need to know what the filename is and where it is trying to find
it. Do you want to include the filename in the context message or
the exception?</p>
<pre class="programlisting">
CONTEXT(&quot;Trying to open &quot; + filename);
if(!FileExists(filename)) {
  throw CException(&quot;Could not find the file &quot;
                    + filename);
}
</pre>
<p>Here we get the filename twice which is cluttered. Throw in some
more context and other redundant sloppiness and you have something
that either needs careful reading or stays unread by the user and
turns into a support call - this in turn makes the user feel less
empowered and costs money.</p>
<p>So the hard bit is writing good consistent messages for the
user. My advice:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Provoke errors (modify if they are not good enough)</p>
</li>
<li>
<p>Have a consistent policy.</p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e208" id="d0e208"></a>When and
where</h2>
</div>
<p>We don't use contexts all the time. Our software is used by the
marine community for various applications around navigation,
planning, tide prediction and so on. The applications involve the
importing and updating of data provided by third parties.
Navigational charts are the obvious example.</p>
<p>It is these complex batch-like bits of the software, say
importing 4000 charts, that most lend themselves to the exceptions
and context error handling strategy. Something goes wrong deep down
and the exception unwinds to a single point where it can be
reported to the user or logged.</p>
<p>The overhead imposed by contexts does not worry us here.</p>
<p>In the day to day GUI use of our applications, when drawing a
route on a chart we have far more control. Exceptional situations
should not happen and performance is an important consideration.
(Drawing performance is something that can separate our
applications from that of competitors). We don't use contexts in
this situation.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
