Что такое правильное сообщение об ошибке для методов Google Guava Preconditions. *? - PullRequest
12 голосов
/ 27 июня 2010

Например, при использовании Preconditions.checkArgument , должно ли сообщение об ошибке отражать случайный случай или случай неудачной проверки?

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

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

Ответы [ 5 ]

21 голосов
/ 27 июня 2010

Для проверок предварительных условий указание требования в сообщении с описанием исключений является более информативным, чем простое изложение фактов. Это также приводит к гораздо более естественному чтению кода:

Документация содержит следующий пример:

Это позволяет такие конструкции, как

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

подлежит замене на более компактный

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

Следует отметить две вещи:

  • В примере четко указывается требование, а не факт
    • " что-то должно быть правильно ", вместо " что-то это неправильно "
  • Обращая условие проверки, вся конструкция более естественным образом читается

Следуя этому примеру, лучше было бы написать:

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

Вы даже можете пойти еще дальше и зафиксировать значения a и b в сообщении об исключении (см. Effective Java 2nd Edition, Item 63: Включить информацию о сбое в подробные сообщения ) :

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

Альтернатива изложения фактов менее естественна для чтения в коде:

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

Обратите внимание, как неловко читать в коде Java одно логическое выражение, за которым следует строка, которая противоречит этому выражению.

Еще одним недостатком констатации фактов является то, что для сложных предварительных условий это потенциально менее информативно, поскольку пользователь может уже знать о факте, но не о том, какие фактические требования нарушаются.

Смежные вопросы

4 голосов
/ 27 июня 2010

В документации приведены примеры, которые делают это очень понятным, используя слова вместо символов:

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

Учитывая, что в основном это просто сообщения об исключениях в журналах (или сеансах отладки), делайте все, что, по вашему мнению, будет понятнее любому, кто смотрит на проблему, или любому, кто читает код, чтобы понять предварительное условие.

Например, вы могли бы переписать вышеприведенное как:

checkArgument(count > 0, "count must be positive; was actually %s", count);
2 голосов
/ 27 июня 2010

Лично для чего-то подобного я думаю написать

checkArgument(a == b, "a (%s) must equal b (%s)", a, b);
0 голосов
/ 07 октября 2016

Как указано полигенные смазки :

Для проверки предварительных условий указание требования в подробном сообщении об исключении более информативно, чем простое изложение фактов.

Хотя вы, безусловно, можете сделать это с помощью предварительных условий для Guava, API требований (который я создал) позволяет вам достичь лучшего результата без каких-либо усилий с вашей стороны.

Предварительные условия для Guava

String a = "foosball";
String b = "ballroom";
Preconditions.checkArgument(a == b, "a == b");

дает вам это:

java.lang.IllegalArgumentException: a == b
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
    at Main.main(Main.java:142)

Требования API

String a = "foosball";
String b = "ballroom";
requireThat(a, "a").isEqualTo(b, "b")

дает вам это:

output

Тот же ввод, лучший вывод.

(Если ваш терминал не поддерживает цвета, вместо этого вы получите текстовый diff)

0 голосов
/ 25 августа 2010

Часто (в большинстве случаев) вы можете просто использовать метод checkArgument () без параметра сообщения об ошибке, то есть вообще не предоставлять сообщение об ошибке.

Чтобы сделатьхорошее сообщение об ошибке нужно понять, кто будет читать сообщение.Это не конечный пользователь;если предварительное условие не выполняется, это, скорее всего, указывает на ошибку в коде.Текст может объяснить невыполненное предварительное условие, но в большинстве случаев оно бесполезно для конечного пользователя, предполагается, что оно является подсказкой для программиста.В большинстве случаев само сообщение также не имеет смысла без трассировки стека и исходного кода.Фактически, в большинстве случаев, трассировка стека и исходный код - это именно то, что нужно программисту для исправления ошибки, сообщение об ошибке не помогает.Если предварительное условие не очевидно, комментарий рядом с ним является идеальным способом для его документирования.

Необходимость всегда предоставлять сообщение об ошибке в тех случаях, когда никто не заботится о тексте, приводит к тому, что программисты делают бесполезными, очевиднымии не полезные сообщения, которые только делают код менее читабельным.

В некоторых случаях сообщение об ошибке может быть полезным, например, сообщение может содержать фактические значения переменных, но, как показывает наш опыт, это не так.очень часто, и в этих случаях вы можете использовать сообщение.

Подобные аргументы применимы также в методах assert в JUnit;всегда предоставлять сообщение об ошибке не очень хорошая идея.

Кроме того, когда вы используете предварительные условия в библиотеке, а не в приложении для конечных пользователей, все может быть иначе, так как вы не знаете, как ваш код будетиспользоваться.

...