Является ли хорошей практикой выбрасывать пользовательское исключение из оператора catch?
У меня есть инструмент командной строки, который запускает тесты. Существует класс бегуна теста, который выполняет некоторую подготовку перед выполнением теста, а затем запускает тест и составляет отчет. Можно ли, если мои классы перехватят исключение и сгенерируют новое пользовательское исключение на верхний уровень, а затем верхний уровень также сгенерирует его на верхний уровень (до класса View, который будет отображать / регистрировать исключение)?
class Program
{
static void Main(string[] args)
{
testRunner = new TestRunner();
try
{
testRunner.RunTest();
testRunner.GetReport();
}
catch (TestRunnerException ex)
{
Print(ex); // prints nicely two levels of exceptions for user
Log(ex); // writes to file all levels of exceptions
}
}
}
class TestRunner
{
void RunTest()
{
// run test here
}
TestReport GetTestReport()
{
try
{
return testReporter.GenerateReport();
}
catch (Exception ex)
{
throw new TestRunnerException("Failed to generate report.", ex);
}
}
}
class TestReporter
{
TestReport GenerateReport()
{
try
{
// create report here
}
catch (Exception ex)
{
throw new ReportException($"Test '{testName}' missing data.", ex)
}
}
}
1 ответ
Это не выбрасывает пользовательское исключение из catch
но ловить все исключения - плохая практика; представить:
TestReport GetTestReport() {
// throws NullReferenceException (yes, GenerateReport() has a bug)
return testReporter.GenerateReport();
}
catch (Exception ex) {
// Bad Practice: here we hide hideous NullReferenceException,
// but throw innocent TestRunnerException
throw new TestRunnerException("Failed to generate report.", ex);
}
...
try {
GetTestReport();
}
catch (TestRunnerException ex) {
// Nothing serious: Tests report fails, let's do nothing
// Under the hood: the routine went very wrong -
// NullReferenceException - in GenerateReport();
;
}
Я предлагаю использовать конкретные исключения в catch
:
TestReport GetTestReport() {
// throws NullReferenceException
return testReporter.GenerateReport();
}
catch (NotAuthorizedException ex) {
// We are not allowed to run tests only, nothing serious
throw new TestRunnerException("Failed to generate report. Not authorized", ex);
}
...
try {
GetTestReport();
}
catch (TestRunnerException ex) {
// Nothing serious: Tests report fails, let's do nothing
;
}