Поймать явные исключения из иерархии - PullRequest
0 голосов
/ 19 мая 2018

У меня есть набор исключений в базовом исключении под названием ServiceException.Это исключение включает явные причины сбоя службы - BadRequestException, ServiceUnreachableException для указания поведения, которое мои классы не могут исправить самостоятельно.

Эта иерархия выглядит примерно так:

public class ServiceException extends Exception {
    public ServiceException() { super(); }

    public ServiceException(String message) { super(message); }

    public ServiceException(String message, Throwable cause) { super(message, cause); }

    public ServiceException(Throwable cause) { super(cause); }
}

и пример одного из подтипов:

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class ServiceUnreachableException extends ServiceException {
    private final String message;
    private final Throwable cause;
}

Когда я собираюсь использовать это, я хотел бы иметь следующую структуру:

public void doProcess() throws ServiceException {
   ...
}

public void processor() {

  try {
    doProcess()
  } catch (BadRequestException e) {
    // Handle specific exception
  } catch (ServiceUnreachableException e) {
    // etc
  } catch (InvalidApiKeyException e) {
    // ...
  }
}

это позволяет мне чистоиспользуйте блоки catch для перехвата различных исключений.Кажется, однако, что Java не может сделать вывод, что исключения генерируются методом doProcess явно через throws ServiceException.

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

public void doProcess() throws BadRequestException, ServiceUnreachableException, InvalidApiKeyException {
   ...
}

public void processor() {

  try {
    doProcess();
  } catch (BadRequestException e) {
    // Handle specific exception
  } catch (ServiceUnreachableException e) {
    // etc
  } catch (InvalidApiKeyException e) {
    // ...
  }
}

или

public void doProcess() throws ServiceException {
   ...
}

public void processor() {

  try {
    doProcess();
  } catch (ServiceException e)  {
     if(e instanceof BadRequestException) {
       // cast and do stuff
     } else if(e instanceof ServiceUnreachableException) {
       // cast and do stuff
     } else if(e instanceof InvalidApiKeyException) {
        //cast and do stuff
     }
  }
}

Что кажется более грязным в обмен на определение метода очистки doProcess.

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

Спасибо!

1 Ответ

0 голосов
/ 19 мая 2018

Кажется, однако, что Java не может сделать вывод, что исключения генерируются методом doProcess явно через throws ServiceException.

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

Что здесь более правильно?

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

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

public void doProcess() throws ServiceException {
   ...
}

public void processor() {
  try {
    doProcess();
  } catch (BadRequestException e) {
    // Handle specific exception
  } catch (ServiceUnreachableException e) {
    // etc
  } catch (InvalidApiKeyException e) {
    // ...
  } catch (ServiceException e) {
    // fallback for any other flavor of ServiceException
    // ...
  }
}

Конечно, это предполагает, что вы хотите избежать processor() объявления любых проверенных исключений;иначе вы могли бы также бросить ServiceException вместо предоставления для него общего блока catch.

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

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