{"id":3273,"date":"2011-03-22T09:00:00","date_gmt":"2011-03-22T09:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2011\/03\/22\/exception-boundaries-working-with-multiple-error-handling-mechanisms\/"},"modified":"2021-10-05T15:55:28","modified_gmt":"2021-10-05T15:55:28","slug":"exception-boundaries-working-with-multiple-error-handling-mechanisms","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/exception-boundaries-working-with-multiple-error-handling-mechanisms\/","title":{"rendered":"Exception Boundaries: Working With Multiple Error Handling Mechanisms"},"content":{"rendered":"<p>\n<a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/03\/6201.image_0AB88986.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/03\/6201.image_0AB88986.png\" alt=\"David Blaikie\" title=\"David Blaikie\" width=\"79\" height=\"104\" class=\"alignleft size-full wp-image-29277\" \/><\/a>\n<\/p>\n<p>Greetings! I&#8217;m <strong>David Blaikie<\/strong>, Software Design Engineer at Microsoft and guest blogger here on <a href=\"http:\/\/blogs.msdn.com\/vcblog\">VCBlog<\/a>. I work in the <strong>Windows product group<\/strong>, writing test infrastructure tools in C++. One of the luxuries of the codebases I work in is that they are relatively modern and flexible. We use the full gamut of C++0x features implemented in <strong>Visual Studio 2010<\/strong> including <a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2008\/10\/28\/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx\">lambdas<\/a> and <a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2009\/02\/03\/rvalue-references-c-0x-features-in-vc10-part-2.aspx\">rvalue references\/move construction<\/a> where possible. At a more fundamental level, we also choose to use <strong>exceptions<\/strong>. <\/p>\n<p>Though I won&rsquo;t get into a debate on the pros and cons of different error handling techniques in this post, it suffices to say that we use exceptions but both our dependencies in some cases (WinAPIs, etc) and some of our users (we have API level exposure to Windows test code sources) don&rsquo;t expose exceptional APIs or build their code with exceptions enabled. To that end, we, like many other developers, need to live our exceptional lives within a possibly unexceptional world. Perhaps you&rsquo;ve encountered similar situations and thought that because the rest of your code base (or your dependencies\/consumers) weren&rsquo;t using exceptions that your own code was just going to have to inherit that design choice.<\/p>\n<p>In fact, there are a variety of simple techniques, reusable code snippets and small library classes you can write to happily insulate your exceptional code from unexceptional consumers and dependencies. <\/p>\n<p>&nbsp;<\/p>\n<h3>Unexceptional Dependencies<\/h3>\n<p>Dealing with dependencies (API functions, classes) that do not use exceptions is fairly simple. Let&rsquo;s first take an example of some simple unexceptional code and see how it might be transformed:<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:acda5f1a-13cf-4c62-bd65-fbaf675eba3c\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2.5em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li>BOOL DiffHandles(HANDLE file1, HANDLE file2); <\/li>\n<li style=\"background: #f3f3f3\"><\/li>\n<li>BOOL DiffFiles(<span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file1, <span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file2) <\/li>\n<li style=\"background: #f3f3f3\">{ <\/li>\n<li>&nbsp;&nbsp;&nbsp; HANDLE file1Handle = CreateFile(file1, GENERIC_READ, &#8230;); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; BOOL result = FALSE; <\/li>\n<li>&nbsp; <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">if<\/span> (file1Handle != INVALID_HANDLE_VALUE) <\/li>\n<li>&nbsp;&nbsp;&nbsp; { <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HANDLE file2Handle = CreateFile(file2, GENERIC_READ, &#8230;); <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">if<\/span> (file2Handle != INVALID_HANDLE_VALUE) <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = DiffHandles(file1Handle, file2Handle); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CloseHandle(file2Handle); <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CloseHandle(file1Handle); <\/li>\n<li>&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> result; <\/li>\n<li>} <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>First things first: Don&rsquo;t use this function. It&rsquo;s good as a demonstration, but as real code it has a bunch of things wrong with it (not to mention it&rsquo;s incomplete anyway).<\/p>\n<p>While this code doesn&rsquo;t seem to have a lot of error handling problems, that&rsquo;s only because the error message handling is done off to the side. <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363858%28v=vs.85%29.aspx\"><span style=\"font-family: courier new\">CreateFile<\/span><\/a>, for example, specifies that if it returns <span style=\"font-family: courier new\">INVALID_HANDLE_VALUE<\/span> it will provide additional error information through <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms679360%28v=vs.85%29.aspx\"><span style=\"font-family: courier new\">GetLastError<\/span><\/a> and we could imagine that <span style=\"font-family: courier new\">DiffHandles<\/span> would have to do the same thing, seeing similar failures from reading from the file (if a network share went away, for example) and would heap those all under a FALSE return value. Users of <span style=\"font-family: courier new\">DiffFiles<\/span> would have to ensure they check <span style=\"font-family: courier new\">GetLastError<\/span> any time that FALSE is returned to them. Not only would it be easy for them to forget and just assume the files were different, rather than that the comparison itself failed (perhaps it&rsquo;s a transient network issue &ndash; the file comparison failed and then the network connection came up again and the files happen to have matching contents. This could cause problems) but also the failures the user of this API receives are vague and any messages shown to the user would be hard for the user to understand or address. While the error value from the function might say that a file was [not found, unable to be read because of permissions, or any other reason] it might not say \/which\/ of the two files had the problem.<\/p>\n<p>So our first step might be to ensure actual failures produce exceptions while the test (are the file contents different) returns false. This will distinguish between the legitimate cases and runtime failures that occurred while attempting to execute the function. In this case our function&rsquo;s type remains the same (though I&rsquo;ll switch to &ldquo;bool&rdquo; now that we don&rsquo;t have a Win32 legacy to interact so directly with) though the contract is different: Return true if the files match, false if the files differ, throw an exception if we couldn&rsquo;t determine whether the files match or not. <\/p>\n<p>We&rsquo;ll introduce a simple helper function to that end:<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f7674300-a0a2-433a-975e-855195ccb7de\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li><span style=\"color: #0000ff\">void<\/span> ThrowLastErrorIf(<span style=\"color: #0000ff\">bool<\/span> expression, <span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* message) <\/li>\n<li style=\"background: #f3f3f3\">{ <\/li>\n<li>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">if<\/span> (!expression) <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; { <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">throw<\/span> Win32Exception(GetLastError(), message); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; } <\/li>\n<li>} <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>This isn&rsquo;t the most advanced form of such a function. We could do much more to create more informative\/human readable error messages. Perhaps <span style=\"font-family: courier new\">Win32Exception<\/span> type could use <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms679351(v=vs.85).aspx\"><span style=\"font-family: courier new\">FormatMessage<\/span><\/a> to produce a human readable message from the error code and append our message string on to that in some manner. In any case, our function can now be rewritten as follows:<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5e048693-067a-405b-b54e-cb97a1b278e0\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2.5em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li><span style=\"color: #0000ff\">bool<\/span> DiffFiles(<span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file1, <span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file2) <\/li>\n<li style=\"background: #f3f3f3\">{ <\/li>\n<li>&nbsp;&nbsp;&nbsp; HANDLE file1Handle = CreateFile(file1, GENERIC_READ, ?); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; ThrowLastErrorIf(file1Handle != INVALID_HANDLE_VALUE, file1); <\/li>\n<li>&nbsp;&nbsp;&nbsp; HANDLE file2Handle = CreateFile(file2, GENERIC_READ, &#8230;); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; ThrowLastErrorIf(file2Handle != INVALID_HANDLE_VALUE, file2); <\/li>\n<li>&nbsp;&nbsp;&nbsp; BOOL result = DiffHandles(file1Handle, file2Handle); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; ThrowLastErrorIf(result == FALSE &amp;&amp; (GetLastError() != MY_APPLICATION_ERROR_FILE_MISMATCH), L<span style=\"color: #a31515\">&#8220;Could not compare file contents&#8221;<\/span>); <\/li>\n<li>&nbsp;&nbsp;&nbsp; CloseHandle(file1Handle); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; CloseHandle(file2Handle); <\/li>\n<li>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> result; <\/li>\n<li style=\"background: #f3f3f3\">} <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>But wait, I (hope I) hear you cry, wouldn&rsquo;t this leak file handles if we throw exceptions? Right you are. While I could&rsquo;ve written this modified version to handle that leak it would&rsquo;ve been somewhat convoluted so instead I&rsquo;m going to demonstrate a better way.<\/p>\n<p>By wrapping up these HANDLEs in a type that can handle their destruction in a more C++, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Resource_Acquisition_Is_Initialization\">RAII<\/a> manner we can not only make this code more readable but also correct (non-leaking)<\/p>\n<div class=\"wlWriterEditableSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c942e5db-c13e-4f7a-a953-314f784673dc\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0 0 0 2.5em;padding: 0 0 0 5px\">\n<li><span style=\"color:#0000ff\">class<\/span> File<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{<\/li>\n<li><span style=\"color:#0000ff\">private<\/span>:<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE handle;<\/li>\n<li>&nbsp;<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color:#008000\">\/\/declared but not defined to avoid double closing<\/span><\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;File&amp; <span style=\"color:#0000ff\">operator<\/span>=(<span style=\"color:#0000ff\">const<\/span> File&amp;);<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;File(File&amp;);<\/li>\n<li><span style=\"color:#0000ff\">public<\/span>:<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;File(<span style=\"color:#0000ff\">const<\/span> <span style=\"color:#0000ff\">wchar_t<\/span>* file)<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handle = CreateFile(file, GENERIC_READ, &#8230;);<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ThrowLastErrorIf(handle, file);<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;}<\/li>\n<li>&nbsp;<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE Get()<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color:#0000ff\">return<\/span> handle;<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;~File()<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(handle);<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;}<\/li>\n<li>};<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>And rewriting the original function again, we get: <\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4d14837a-b432-4a0b-8699-53bfd11427ff\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li><span style=\"color: #0000ff\">bool<\/span> DiffFiles(<span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file1, <span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file2) <\/li>\n<li style=\"background: #f3f3f3\">{ <\/li>\n<li>&nbsp;&nbsp;&nbsp; File f1(file1); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; File f2(file2); <\/li>\n<li>&nbsp;&nbsp;&nbsp; result = DiffHandles(f1.Get(), f2.Get()); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; ThrowLastErrorIf(result == FALSE &amp;&amp; (GetLastError() != MY_APPLICATION_ERROR_FILE_MISMATCH), L<span style=\"color: #a31515\">&#8220;Could not compare file contents&#8221;<\/span>); <\/li>\n<li>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> result; <\/li>\n<li style=\"background: #f3f3f3\">} <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>All without leaks and the need to pay close attention to code paths to ensure resource destruction.<\/p>\n<p>It&rsquo;s not quite the same as it would be if <span style=\"font-family: courier new\">DiffHandles<\/span> was an exception-aware API, but it tidies up the function a bit and means that unexceptional dependencies don&rsquo;t pollute our exception-aware codebase.<\/p>\n<p>The implementation of the Win32Exception type and enhancements to the <span style=\"font-family: courier new\">ThrowLastErrorIf<\/span> function (to include mapping specific result values to already well known exception types such as <span style=\"font-family: courier new\">std::bad_alloc<\/span>) is left as an exercise for the reader.<\/p>\n<p>&nbsp;<\/p>\n<h3>Unexceptional Consumers<\/h3>\n<h4>Types of Unexceptional Consumers<\/h4>\n<p>We&rsquo;ve seen that Win32 &ldquo;invalid return (FALSE, INVALID_HANDLE_VALUE, etc) + GetLastError&rdquo; is one kind of unexceptional error message scheme. Other APIs you might run into that have an unexceptional boundary include C code (indeed Win32&rsquo;s API is a specific case of this, but POSIX uses int return values and errno to similar effect) or HRESULT returning COM APIs. <\/p>\n<p>[While it might not be immediately obvious why it&rsquo;s worth considering C code as an unexceptional consumer (&ldquo;my users will be writing in C, so my library must be in C&rdquo; I hear you cry) it&rsquo;s actually quite possible to write a C API in C++. By declaring your functions with <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/0603949d%28v=vs.80%29.aspx\">extern &ldquo;C&rdquo;<\/a> you can have C linkage functions in a C++ compilation unit using the full functionality of the C++ programming language in your implementation]<\/p>\n<p>&nbsp;<\/p>\n<h4>Dealing with Unexceptional Consumers<\/h4>\n<p>Dealing with unexceptional consumers is perhaps a little trickier, though the most basic implementation is not terribly difficult, if a little verbose and lossy. Let&rsquo;s invert the above example. Imagine we had the original <span style=\"font-family: courier new\">DiffFiles<\/span>, but we wanted to keep the interface (BOOL do_things + <span style=\"font-family: courier new\">GetLastError<\/span>) but we had updated our dependencies (File handling using RAII resource wrappers as shown, as well as updating <span style=\"font-family: courier new\">DiffHandles<\/span>, or using the STL) to be exception-aware themselves. As such they no longer return failures through <span style=\"font-family: courier new\">GetLastError<\/span>, instead returning bool and throwing exceptions for their failures. Perhaps not even <span style=\"font-family: courier new\">Win32Exception<\/span> failures (this particular exception type wouldn&rsquo;t be used pervasively, but only when interacting with unexceptional APIs where no more accurate exception type was available to represent the failure).&nbsp; We could simply rewrite the <span style=\"font-family: courier new\">DiffFiles<\/span> function as follows:<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0acb10f4-45bd-4016-b483-f8a393277f0f\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2.5em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li>BOOL DiffFiles(<span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file1, <span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file2) <\/li>\n<li style=\"background: #f3f3f3\">{ <\/li>\n<li>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">try<\/span> <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; { <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f1(file1); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f2(file2); <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">if<\/span> (!DiffHandles(f1, f2)) <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetLastError(MY_APPLICATION_ERROR_FILE_MISMATCH); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> FALSE; <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> TRUE; <\/li>\n<li>&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">catch<\/span>(<span style=\"color: #0000ff\">const<\/span> Win32Exception&amp; e) <\/li>\n<li>&nbsp;&nbsp;&nbsp; { <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetLastError(e.GetErrorCode()); <\/li>\n<li>&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">catch<\/span>(<span style=\"color: #0000ff\">const<\/span> std::exception&amp; e) <\/li>\n<li>&nbsp;&nbsp;&nbsp; { <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetLastError(MY_APPLICATION_GENERAL_ERROR); <\/li>\n<li>&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> FALSE; <\/li>\n<li>} <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>You should be sure to catch any\/all exceptions which could be produced by the code in the try block. In this case we know that the File class and <span style=\"font-family: courier new\">DiffHandles<\/span> function can only throw <span style=\"font-family: courier new\">Win32Exceptions<\/span> so we can just handle that.<\/p>\n<p>With this basic implementation we lose all exception detail, even those details we could map to interesting results (perhaps <span style=\"font-family: courier new\">std::bad_alloc<\/span> could be mapped to an out of memory Win32 error code for example), so it&rsquo;s not ideal. Again, we could imagine putting a variety of catch blocks in to map different exception types to various failures, adding logging to record the full details of the exception (since we&rsquo;ll be compressing entire exception objects including strings of context, stack traces, etc, into a single win32 error code) before it is coalesced into a single value for return, etc. In doing so every one of the functions on our unexceptional public interface is going to get long and unwieldy. <\/p>\n<p>&nbsp;<\/p>\n<h4>Macros as an Exception Consuming Boundary<\/h4>\n<p>To reduce the syntactic overhead in this case we can use macros to implement a convenient wrapper to hide all that possible complexity and repeated logic: <\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bfdd8b1c-f347-49b3-8b09-10a12f6f0ed4\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li><span style=\"color: #0000ff\">#define<\/span> WIN32_START <span style=\"color: #0000ff\">try<\/span> { <\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">#define<\/span> WIN32_END } <span style=\"color: #0000ff\">catch<\/span> (<span style=\"color: #0000ff\">const<\/span> Win32Exception&amp; e) { SetLastError(e.GetErrorCode()); } <span style=\"color: #0000ff\">catch<\/span> (<span style=\"color: #0000ff\">const<\/span> std::exception&amp; e) { SetLastError(MY_APPLICATION_GENERAL_ERROR); } <span style=\"color: #0000ff\">return<\/span> FALSE; <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>The do_things function then becomes:<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:65758664-3bcf-4f4f-9dd4-610774d956d2\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2.5em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li>BOOL DiffFiles(<span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file1, <span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">wchar_t<\/span>* file2) <\/li>\n<li style=\"background: #f3f3f3\">{ <\/li>\n<li>&nbsp;&nbsp;&nbsp; WIN32_START <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f1(file1); <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f2(file2); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">if<\/span> (!DiffHandles(f1, f2)) <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetLastError(MY_APPLICATION_ERROR_FILE_MISMATCH); <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> FALSE; <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> TRUE; <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; WIN32_END <\/li>\n<li>} <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>While macros provide an obvious way to implement this functionality they can make code hard to debug and analyze.<\/p>\n<p>&nbsp;<\/p>\n<h4>Lambdas as an Exception Consuming Boundary<\/h4>\n<p>We can tidy this up a little further, replacing macros with lambdas as follows:<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4e84397e-57f0-47d2-ba23-34e4b7d26da8\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border-bottom: #000080 1px solid;border-left: #000080 1px solid;font-family: 'Courier New', courier, monospace;color: #000;font-size: 10pt;border-top: #000080 1px solid;border-right: #000080 1px solid\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"padding-bottom: 0px;margin: 0px 0px 0px 2.5em;padding-left: 5px;padding-right: 0px;background: #ffffff;padding-top: 0px\">\n<li><span style=\"color: #0000ff\">template<\/span>&lt;<span style=\"color: #0000ff\">typename<\/span> Func&gt; <\/li>\n<li style=\"background: #f3f3f3\">BOOL Win32ExceptionBoundary(Func&amp;&amp; f) <\/li>\n<li>{ <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">try<\/span> <\/li>\n<li>&nbsp;&nbsp;&nbsp; { <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> f(); <\/li>\n<li>&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">catch<\/span>(<span style=\"color: #0000ff\">const<\/span> Win32Exception&amp; e) <\/li>\n<li>&nbsp;&nbsp;&nbsp; { <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetLastError(e.GetErrorCode()); <\/li>\n<li>&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">catch<\/span>(<span style=\"color: #0000ff\">const<\/span> std::exception&amp; e) <\/li>\n<li>&nbsp;&nbsp;&nbsp; { <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetLastError(MY_APPLICATION_GENERAL_ERROR); <\/li>\n<li>&nbsp;&nbsp;&nbsp; } <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">return<\/span> FALSE; <\/li>\n<li>} <\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>With this function, we can now reduce our do_things() function to:<\/p>\n<div class=\"wlWriterEditableSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:481fa96f-2dc5-4205-a11f-05aba55b6775\" style=\"padding-bottom: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;float: none;padding-top: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #ddd;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0 0 0 2.5em;padding: 0 0 0 5px\">\n<li>BOOL DiffFiles(<span style=\"color:#0000ff\">const<\/span> <span style=\"color:#0000ff\">wchar_t<\/span>* file1, <span style=\"color:#0000ff\">const<\/span> <span style=\"color:#0000ff\">wchar_t<\/span>* file2) <\/li>\n<li style=\"background: #f3f3f3\">{ <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color:#0000ff\">return<\/span> Win32ExceptionBoundary([&amp;]() -&gt; BOOL<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{ <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File f1(file1); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File f2(file2); <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color:#0000ff\">if<\/span> (!DiffHandles(f1, f2)) <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetLastError(MY_APPLICATION_ERROR_FILE_MISMATCH); <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color:#0000ff\">return<\/span> FALSE; <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color:#0000ff\">return<\/span> TRUE; <\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}); <\/li>\n<li style=\"background: #f3f3f3\">}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>The <span style=\"font-family: Courier New\">Win32ExceptionBoundary<\/span> could be generalized (so it could be used with, say, <span style=\"font-family: Courier New\">HANDLE<\/span> returning functions) by taking the error result as an extra parameter and using that to infer the return type of the template function, for example.<\/p>\n<p>&nbsp;<\/p>\n<h3>Summary<\/h3>\n<p>With tools such as these you can introduce exception-aware code into your code base, enabling you to take advantage of the myriad of carefully implemented and tested standard libraries such as containers, smart pointers, and algorithms without having to revamp your entire codebase. Your exception-aware walled garden can grow as time and business justification permits, converting single functions\/libraries at a time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Greetings! I&#8217;m David Blaikie, Software Design Engineer at Microsoft and guest blogger here on VCBlog. I work in the Windows product group, writing test infrastructure tools in C++. One of the luxuries of the codebases I work in is that they are relatively modern and flexible. We use the full gamut of C++0x features implemented [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[84],"class_list":["post-3273","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-exception-handling"],"acf":[],"blog_post_summary":"<p>Greetings! I&#8217;m David Blaikie, Software Design Engineer at Microsoft and guest blogger here on VCBlog. I work in the Windows product group, writing test infrastructure tools in C++. One of the luxuries of the codebases I work in is that they are relatively modern and flexible. We use the full gamut of C++0x features implemented [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3273","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=3273"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3273\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=3273"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=3273"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=3273"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}