Alex Rivera | Logout

What is the proper error message to supply to Google Guava's Preconditions.* methods?

Asked 2010-06-27T17:09:13.497
12

For example when using Preconditions.checkArgument, is the error message supposed to reflect the passing case or the failing case of the check in question?

import static com.google.common.base.Preconditions.*;

void doStuff(int a, int b) {
  checkArgument(a == b, "a == b");
  // OR
  checkArgument(a == b, "a != b");
}
Edit
Report

1 Answer

21

For precondition checks, stating the requirement in the exception detail message is more informative than simply stating the facts. It also leads to a lot more naturally reading code:

The documentation provides the following example:

This allows constructs such as

 if (count <= 0) {
   throw new IllegalArgumentException("must be positive: " + count);
 }

to be replaced with the more compact

 checkArgument(count > 0, "must be positive: %s", count);

Two things are of note:

  • The example clearly states requirement, rather than the fact
    • "something must be right", instead of "something is wrong"
  • By inverting the condition of the check, the entire construct read more naturally

Following that example, a better message would be:

checkArgument(a == b, "a must be equal to b"); // natural!

You can even go a step further and capture the values of a and b in the exception message (see Effective Java 2nd Edition, Item 63: Include failure capture information in detail messages):

checkArgument(a == b, "a must be equal to b; instead %s != %s", a, b);

The alternative of stating facts is less natural to read in code:

checkArgument(a == b, "a != b");              // awkward!
checkArgument(a == b, "a is not equal to b"); // awkward!

Note how awkward it is to read in Java code one boolean expression, followed by a string that contradicts that expression.

Another downside to stating facts is that for complicated preconditions, it's potentially less informative, because the use

answered 2010-06-27T18:07:16.580

Your Answer