3

From time to time (unfortunately way too often) I have to fix code such as this:

// C++ code
bool anyOldFunction(Param p) {
  try {
  ...
  if(some_condition_here) {
    handleErrorX();
    return false;
  } else if(other_condition) {
    return false; // (*stackexchange question comment*) Apparently no additional error action taken here
  }
  ...
  return true;
  } catch(...) {
    // (*old comment*) Catch all possible error (FroobleFub and BrabbleBub can happen)
    return false;
  }
}

So, the original implementer actually had some inkling what exceptions could be thrown (although the list may not be exhaustive) but had no idea how to do some decent handling and just discarded any info he might have gotten out of the exception objects, leaving the calling code / the calling context non-the-wiser.

Is there a name for this anti-pattern? (If anti-pattern it is indeed.)

3
  • 2
    "job protection" ? :-)
    – Jalayn
    Sep 5, 2011 at 9:38
  • 9
    Don't assume the code is broken just because it swallows exceptions. If the contract is to return true on success and false on failure, the caller will get exactly what it is expecting. Altering the code to start throwing exceptions at callers that were written to assume there won't be any could cause a working system to break, and you'll have to kick the can up the road and swallow the exceptions elsewhere.
    – Blrfl
    Sep 5, 2011 at 12:54
  • looks like the programmer originally was a C programmer, who didn't fully understand why to use Exceptions.
    – Rommudoh
    Sep 6, 2011 at 12:28

3 Answers 3

10

"Exception Swallowing" (a discussion of it on Phil Haack's blog: https://web.archive.org/web/20110906115349/http://haacked.com/archive/2005/08/10/9293.aspx)

or

"Error Hiding": http://en.wikipedia.org/wiki/Error_hiding

While you are coding in C++ and I'm not sure about its mechanisms when handling exceptions, the main problem with exception swallowing in .NET managed code, is that if it is rethrown or a new exception is created without the original included, the stack trace to the original cause of the failure is not included, which makes debugging slightly harder, as you have discussed in your question.

1
  • 1
    (nitpicking) starting with 3.5, rethrown in different method => stack trace will contain both locations. Rethrown in same method => only the rethrow location will be shown. But I agree this is a real danger, not just on .Net but on any kind of stack-trace mechanisms.
    – rwong
    Sep 5, 2011 at 11:03
3

direct answer to your question: I most commonly hear it referred to as swallowing or eating the error.

Indirect answer: It is not always an undesirable pattern. Sometimes this pattern is desirable when you absolutely do not want the error detail leaving the tier/class/function/whatever you are currently in. Data access was (is still in some instances) famous for including sensitive info in exception detail. It is was fairly common in several past jobs to see exception blocks like that so that internal details were not exposed just by someone making a resource unavailable. I sometimes heard people call this safe exceptions or secure failure.

The other place where I still see that pattern is where the exception detail just isn't important. For example, when interacting with an external library that does not have a good way to check preconditions or lock a changing variable for example sometimes you just have to make the call and if it exceptions you know the value isn't available. If you have another way to continue it is more efficient to consume the error as low as possible and pass a flag than to unwind the stack at every level with a whole mess of catch blocks.

You could certainly change it (and all it's calling methods to include extra catch blocks & not to rely of the return flag), but unless you have something meaningful that you can do with the exception detail at the next higher level and there is no risk of showing all the possible exceptions and stack business all you are doing is creating more places you have to code slow catch blocks.

2
  • Bill - Thanks for elaborating. Would you mind clarify if the experience you cite is in C++ or another language? -- Esp. wrt. the external library and the catch(...).
    – Martin Ba
    Sep 6, 2011 at 5:44
  • Sorry, I crossed my topics a bit there. The catch performance comment mostly MS languages (most evident in .NET languages) but the efficiency of catching low or passing exceptions out in all cases is going to relate somewhat to any language that does not support a central error handler concept. The exception detail security is true in all sorts of languages that pass underlying provider errors.
    – Bill
    Sep 9, 2011 at 2:44
0

There are many situations where the caller only cares about success or failure. There are other situations where the caller wants some information, and other cases where they want all the information.

Swift uses “try” - ordinary error handling, “try!” - any error crashes immediately, and “try?” - errors return failure with no information about the error. Quite flexible and easy to use.

You often have a situation where a library should return an exact error description to help with debugging, but the caller will only return error or failure to its caller. The important thing is that if the user can do something to fix the problem, we need to tell them how to fix it. And if there is nothing they can do the same. (“Try again in five minutes”, and “Call your admin”, and “Didn’t work, nothing you can do”) are valid responses).

2
  • "There are many situations where the caller only cares about success or failure." - never me as caller! Not in my code, not as user. If I do/trigger something, then in the error case "Computer Says No" is never what I want to hear. (It may be that my code can't do anything about it in the end, but I always want to report, or get reported, some cause.) :-)
    – Martin Ba
    Jul 1, 2021 at 9:54
  • Martin, you usually have more than one level. In one app, I have a method “read data from URL”. It calls a success callback or a failure callback. In between it asks the user to turn WiFi or mobile data on, handles timeouts, etc. etc. To the caller, it reports success or failure.
    – gnasher729
    Jul 1, 2021 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.