Почему большинство исключений исключают информацию о конкретном экземпляре?

Я заметил, что большинство сообщений об исключениях не содержат подробные сведения о экземпляре, такие как значение, вызвавшее исключение. Обычно они сообщают вам только о "категории" ошибки.

Например, при попытке сериализации объекта с третьим. я получил сообщение MissingMethodException с сообщением:

"Для этого объекта не определен конструктор без параметров".

Во многих случаях этого достаточно, но часто (обычно во время разработки) сообщение типа

"Для этого объекта типа" Foo "не определен конструктор без параметров.

может сэкономить много времени, направляя вас прямо на причину ошибки.

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

Это сделано специально?

Есть ли влияние безопасности при экспонировании внутреннего состояния, такого как "ошибочное" значение переменной?

Ответ 1

Две причины, о которых я могу думать:

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

Во-вторых, и что еще более важно, это то, что действительно может быть риск безопасности, который может быть очень трудно повторить (если я пишу универсальный контейнер, я не знаю, какие контексты он будет используется в). Мы не хотим, чтобы "Credit-Card: 5555444455554444" появлялась в сообщении об ошибке, если мы можем помочь.

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

Ответ 2

InvalidArgumentException и (за @Ian Nelson) "Ключ, не найденный в словаре", совместно используют что-то общее - нет гарантии, что структура сможет найти подходящее значение, чтобы показать вам - если ключ/аргумент любого пользовательского типа, а ToString() не был переопределен, тогда вы просто получите имя типа - оно не добавит большого значения.

Ответ 3

Исключения в основном предназначены для использования программой. Большинство программ не знали, что делать с информацией об экземпляре.

Свойство Message предназначено для потребления человеком. Помимо сценария отладки, люди не будут знать, что делать с Foo.

Ответ 4

Многие механизмы исключения пытаются служить мешанине ортогональных целей, передавая один объект, созданный исключаемыми:

  • Предоставление вызывающему абоненту информации о том, что произошли различные конкретные вещи или существуют различные конкретные проблемы.
  • Определение, когда исключительное условие "разрешено", чтобы нормальный поток программы продолжался.
  • Предоставление указания о том, что сообщить пользователю о программе
  • Предоставление информации, которая может быть зарегистрирована, чтобы позволить владельцам системы идентифицировать проблемы, когда имеется безопасный журнал
  • Предоставление информации, которая может быть зарегистрирована, чтобы позволить владельцам системы идентифицировать проблемы, но которые не будут представлять угрозу безопасности, даже если безопасное ведение журнала недоступно.

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