Note that there are some explanatory texts on larger screens.

plurals
  1. POC++ error handling pattern
    text
    copied!<p>We have a large code base with a lot of code which does this kind of thing:</p> <pre><code>bool DoSomething(CString Value) { if(Value == "bad") { AfxMessageBox("description of error"); return false; } return true; } </code></pre> <p>or even just this:</p> <pre><code>bool DoSomething(CString Value) { if(Value == "bad") { return false; } return true; } </code></pre> <p>We have considered various alternatives:</p> <ul> <li>Exceptions - Basically we’re sold on the cons as described here: <a href="http://www.codeproject.com/Articles/38449/C-Exceptions-Pros-and-Cons" rel="nofollow noreferrer">http://www.codeproject.com/Articles/38449/C-Exceptions-Pros-and-Cons</a></li> <li>Passing an additional string ref parm which is populated with error text - but it requires a pre-instantiation of the error string prior to the call, and adds bulk to the parm lists</li> <li>Populating a ‘last_error’ member variable - this seems to suffer (imo) the drawbacks expressed here: <a href="https://stackoverflow.com/questions/9099981/is-getlasterror-kind-of-design-pattern-is-it-good-mechanism">Is GetLastError() kind of design pattern? Is it good mechanism?</a></li> <li>Passing back an enum (or the like) which can be mapped to a description of the error with some other function - but this feels ‘heavy’ for small functions and objects, and also creates space between the place the error occurs and the place where the messages are maintained (though I suppose in multi-ligual environment they’d appreciate the centralization of the text).</li> </ul> <p>So I wondered if we could create a set of classes like the following:</p> <pre><code>class CResult { protected: CResult() { // Don't have to initialize because the derived class will do it } public: operator bool() { return m_Result; }; bool m_Result; CString m_Message; }; class CSuccess : public CResult { public: CSuccess() { m_Result = true; } }; class CFailure : public CResult { public: CFailure(const CString &amp; Message) { m_Result = false; m_Message = Message; } }; </code></pre> <p>Then the above code could look like this:</p> <pre><code>CResult DoSomething(CString Value) { if(Value == "bad") { return CFailure("description of error"); } return CSuccess(); } </code></pre> <p>What I like about it:</p> <ul> <li>The code is still readable and the error message is maintained near the error condition</li> <li>The programmer will be slightly more compelled to actually provide an error string on an error condition (yes, they could provide blanks but that would seem a more egregious mistake, imo)</li> <li>The caller doesn’t have to create any specialized variables prior to the function call, and can still treat the function result like a bool - or in a case where the error is not ignored, easily retrieve an explanation</li> <li>The next programmer can what error model is in use just by looking at the function definition</li> </ul> <p>The main drawback I see is that there is higher overhead on success, in that an object and a string and a bool will all be instantiated - but a lot of the times in our app the code in question is not performance sensitive, such as validating user input, etc.</p> <p>Am I missing some other big drawback? Is there an even better solution?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload