З нашим загальнодоступним SDK ми, як правило, хочемо надсилати дуже інформативні повідомлення про те, чому відбувається виняток. Наприклад:
if (interfaceInstance == null)
{
string errMsg = string.Format(
"Construction of Action Argument: {0}, via the empty constructor worked, but type: {1} could not be cast to type {2}.",
ParameterInfo.Name,
ParameterInfo.ParameterType,
typeof(IParameter)
);
throw new InvalidOperationException(errMsg);
}
Однак це, як правило, захаращує потік коду, оскільки, як правило, робить велику увагу на повідомленнях про помилки, а не на те, що робить код.
Колега почав перетворювати деякі винятки, кидаючи щось подібне:
if (interfaceInstance == null)
throw EmptyConstructor();
...
private Exception EmptyConstructor()
{
string errMsg = string.Format(
"Construction of Action Argument: {0}, via the empty constructor worked, but type: {1} could not be cast to type {2}.",
ParameterInfo.Name,
ParameterInfo.ParameterType,
typeof(IParameter)
);
return new InvalidOperationException(errMsg);
}
Це полегшує розуміння логіки коду, але додає багато додаткових методів для обробки помилок.
Які ще способи уникнути проблеми "логіки, що заважають довгим виняткам"? Я в першу чергу запитую про ідіоматичну C # /. NET, але як корисні інші мови.
[Редагувати]
Було б непогано мати і плюси і мінуси кожного підходу.
Exception.Dataвластивості, "прискіпливого" вилучення винятків, виклику коду та додавання власного контексту, а також стека захоплених викликів вносять інформацію, яка повинна дозволяти набагато менше багатослівних повідомлень. Нарешті, це System.Reflection.MethodBaseвиглядає багатообіцяючим щодо надання деталей для переходу до вашого методу "побудова виключень".
Exception.Data. Акцент повинен бути захоплено телеметрією. Рефакторинг тут прекрасний, але він пропускає проблему.