Возвратите исключение в операторе switch и затем бросьте вызываемый метод - PullRequest
2 голосов
/ 16 октября 2019

У меня есть два метода

private String handleResponse(HttpResponse httpResponse){
    if (response.getStatusCode() / 100 == 2) {
        return response.getEntity().toString()
    } else {
        throw handleException(response.getStatusCode());
    }
}
private RuntimeException handleException(int errorStatusCode){
    switch(errorStatusCode) {
        case 400:
            return new RuntimeException("Invalid request");
        case 401:
            return new RuntimeException("User not authorized");
        default:
            return new RuntimeException("Unkown exception");
    }
}

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

Ответы [ 3 ]

1 голос
/ 17 октября 2019
  1. Избавиться от response.getStatusCode() / 100 == 2. Вместо этого напишите response.getStatusCode() == 200 или response.getStatusCode() == HttpStatus.SC_OK.

  2. Удалите ветвь else и throw после оператора if.

  3. Переименуйте метод в getExceptionByStatusCode или generateExceptionForStatusCode. Вы не handleException, вы решаете, какой из них бросить.

  4. Выберите правильный тип возврата. Не используйте RuntimeException. Это может быть ResponseStatusException или любой другой тип, соответствующий HTTP / абстракции вашего домена.

  5. Для каждого случая решите, какой тип вы хотите вернуть. Опять же, не RuntimeException.

Немного улучшенная версия будет

private String handleResponse(HttpResponse response) {
    final int statusCode = response.getStatusCode();

    if (statusCode == HttpStatus.SC_OK) {
        return response.getEntity().toString();
    }

    throw getExceptionByStatusCode(statusCode);
}

private MyDomainHTTPException getExceptionByStatusCode(int statusCode) {
    switch (statusCode) {
        case HttpStatus.SC_NOT_FOUND:
            return new MyDomainHTTPException("...");
        case HttpStatus.SC_UNAUTHORIZED:
            return new MyDomainHTTPException("...");
        default:
            return new MyDomainHTTPException("...");
    }
}

Тем не менее, возвращение исключения в Java не чувствовать верно.

Работает нормально, но не совсем корректно из-за «особого» статуса исключений. Это может быть оправдано при ленивых оценках, и вы будете выдавать исключение, когда встретите определенное условие в будущем или в случаях с Optional.orElseThrow.

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

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

1 голос
/ 17 октября 2019

Вы можете сделать его немного короче и интуитивно понятным следующим образом:

private String handleResponse(HttpResponse httpResponse){
    if (response.getStatusCode() == 200) {
        return response.getEntity().toString()
    } else {
        throw new RuntimeException(getErrorMessage(response.getStatusCode());
    }
}

private String getErrorMessage(int errorStatucCode){
    switch(errorStatucCode) {
        case 400:
            return "Invalid request";
        case 401:
            return "User not authorized";
        default:
            return "Unkown exception";
}
0 голосов
/ 17 октября 2019

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

private String handleResponse(HttpResponse httpResponse){
    if (response.getStatusCode() / 100 == 2) {
        return response.getEntity().toString()
    } else {
        throwException(response.getStatusCode());
    }
}

private void throwException(int errorStatusCode){
    switch(errorStatusCode) {
        case 400:
            throw new RuntimeException("Invalid request");
        case 401:
            throw new RuntimeException("User not authorized");
        default:
            throw new RuntimeException("Unkown exception");
    }
}

API, который я вызываю, может вернутькак успешный ответ 200, 201, 204. Но я открыт для любых предложений.

Если вы примете любой код состояния 2xx, как насчет:

if (response.getStatusCode() >= 200 && response.getStatusCode() <= 299) {
...