Подтвердить что ты не робот

Кэш Guava и сохранение проверенных исключений

Я рефакторинг некоторого кода для использования кэша guava.

Исходный код:

public Post getPost(Integer key) throws SQLException, IOException {
    return PostsDB.findPostByID(key);
}

Чтобы не сломать что-то, мне нужно сохранить любое заброшенное исключение как есть, без его обертки.

Текущее решение выглядит несколько уродливым:

public Post getPost(final Integer key) throws SQLException, IOException {
    try {
        return cache.get(key, new Callable<Post>() {
            @Override
            public Post call() throws Exception {
                return PostsDB.findPostByID(key);
            }
        });
    } catch (ExecutionException e) {
        Throwable cause = e.getCause();
        if (cause instanceof SQLException) {
            throw (SQLException) cause;
        } else if (cause instanceof IOException) {
            throw (IOException) cause;
        } else if (cause instanceof RuntimeException) {
            throw (RuntimeException) cause;
        } else if (cause instanceof Error) {
            throw (Error) cause;
        } else {
            throw new IllegalStateException(e);
        }
    }
}

Есть ли какой-нибудь возможный способ сделать его более приятным?

4b9b3361

Ответ 1

Сразу после написания вопроса начали задумываться о полезности метода с использованием дженериков. Потом вспомнил кое-что о Throwables. И да, это уже там! )

Также может потребоваться обработать UncheckedExecutionException или даже ExecutionError.

Итак, решение таково:

public Post getPost(final Integer key) throws SQLException, IOException {
    try {
        return cache.get(key, new Callable<Post>() {
            @Override
            public Post call() throws Exception {
                return PostsDB.findPostByID(key);
            }
        });
    } catch (ExecutionException e) {
        Throwables.propagateIfPossible(
            e.getCause(), SQLException.class, IOException.class);
        throw new IllegalStateException(e);
    } catch (UncheckedExecutionException e) {
        Throwables.throwIfUnchecked(e.getCause());
        throw new IllegalStateException(e);
    }
}

Очень хорошо!

Смотрите также ThrowablesExplained, LoadingCache.getUnchecked и Почему мы устарели Throwables.propagate.