質問

We have a piece of code that looks something like that:

std::vector<int> computeGlobalResult()
   {
   auto globalResult = std::vector<int>{};
   while (myCollection.size() < 100)
      {
      auto localResult = computeLocalResult();
      globalResult.emplace(globalResult.end(), localResult.begin(), localResult.end());
      }
   return globalResult;
   }

We have a strong assumption that the computeLocalResult() function should never return an empty collection. However, due to bugs in the computeLocalResult() function we had a couple of times the issue that the computeGlobalResult() function got stuck in the while loop causing the application to hang. This resulted in our users logging bugs about the application hanging and this allowed us to easily pin point and solve the issues. However since this hanging happened multiple times we are wondering if we should do something to prevent it. The reason behind this reasoning is that the application hanging is an inconvenience to the user and reflects badly on the perceived quality of the software. One way to achieve it could be by doing something like this:

std::vector<int> computeGlobalResult()
   {
   auto globalResult = std::vector<int>{};
   while (myCollection.size() < 100)
      {
      auto localResult = computeLocalResult();
      if (localResult.empty())
         break;
      globalResult.emplace(globalResult.end(), localResult.begin(), localResult.end());
      }
   return globalResult;
   }

The side effect of this is that by doing so, the application will silently return a (possibly incorrect) result to the user. As a result we are much less likely to get a bug report out of it and solve the underlying issue.

In order to minimize this bug reporting problem, in case computeLocalResult() returns an empty collection, one could imagine logging the inconsistency as well as all necessary data needed to be able to reproduce the issue. See the next code snippet for an example:

std::vector<int> computeGlobalResult()
   {
   auto globalResult = std::vector<int>{};
   while (myCollection.size() < 100)
      {
      auto localResult = computeLocalResult();
      if (localResult.empty())
         {
         logErrorAndInputDataForReproduction();
         break;
         }
      globalResult.emplace(globalResult.end(), localResult.begin(), localResult.end());
      }
   return globalResult;
   }

However, since our application runs on customer premise, there is no guarantee that we will ever get bug reports and those logs (since to the end user it could seem that everything is working fine).

Is there an approach that I have missed that would avoid having the application hanging, while still maximizing our chances to get a bug report to be able to fix the issue?

役に立ちましたか?

解決

This is why you display an error message.

Anything less is putting the blame on garbage in, garbage out. You should be doing garbage in, informative error message out. If something is wrong you need a way to communicate that something is wrong. Hanging is not a good way to do that. Failing silently is not a good way to do that. Logging an error is good but also tells the typical user nothing. Garbage in, garbage out with a log that no one thinks to look at is not good. Display an error message. That way the user knows that what they wanted done didn't happen. If you can't put the program back into a stable usable state then roll over and die.

The only system better than this is garbage in, call home and log the error on a developers box. Which, as cmaster correctly points out, if you're going to do you'll need consent. But even then, you still need to tell the user they didn't get what they expected.

ライセンス: CC-BY-SA帰属
所属していません softwareengineering.stackexchange
scroll top