Есть ли шаблон для выполнения нескольких функций броска друг за другом? - PullRequest
0 голосов
/ 31 октября 2018

Я ищу хороший способ написать код с исключениями, если я хочу игнорировать их в куске кода.

Рассмотрим

bool ClearAllCaches() {
    bool success = ClearPersistentCache();
    success &= ClearTransientCache();
    success &= ClearRemoteCache();
    return success;
}

Если эти функции выбрасывали, а не возвращали значение успеха, и я также хочу перебросить любое исключение, что один из этих бросков, но только после того, как все выполнено, есть ли более чистое решение, чем это?

void ClearAllCaches() {
    MyException persistentException = MyException(ErrorCode::None);
    try {
        ClearPersistentCache();
    } catch (const MyException& e) {
        persistentException = e;
    }
    //...same for ClearTransientCache()
    ClearRemoteCache(); // <- does not have to be caught.
    if (persistentException.getCode() != ErrorCode::None) {
        throw persistentException;
    }
    //...same for ClearTransientCache()
}

Можно ли написать это читабельным и не слишком уродливым образом?

1 Ответ

0 голосов
/ 31 октября 2018

Используйте лямбду и std::exception_ptr:

void ClearAllCaches() {
    std::exception_ptr eptr;
    auto CallAndStoreException = [&](auto func) {
        try {
            func();
        } catch (...) {
            eptr = std::current_exception();
        }
    };

    CallAndStoreException(&ClearPersistentCache);
    CallAndStoreException(&ClearTransientCache);
    CallAndStoreException(&ClearRemoteCache);

    if (eptr) {
        std::rethrow_exception(eptr);
    }
}

Но вы уверены, что исключения - правильный путь, если вы выбрасываете информацию о тех, кого выбросили первыми? Если вы уверены, что должны идти по этому пути, возможно, посмотрите также std::nested_exception

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