Три версии обработки исключений, какая из них предпочтительнее? - PullRequest
1 голос
/ 23 сентября 2010

Я реализую Zip-Wrapper (zlib minizip) и спрашиваю себя, как правильно обрабатывать исключения.Я думаю о трех версиях.Какой вариант вы бы предпочли, или есть версия, о которой я не думал?

Задача функции Install - получить Zip-файл с веб-сервера, распаковать его содержимое и удалитьскачанный Zip-файл.Но если при распаковке файла возникает ошибка, где следует удалить Zip-файл?

Резервуары для вашего опыта.

Версия A (с удалением вне функции):

void Install() {
    getFile("upd.zip"); // Creates File
    MyZip myzip("upd.zip");
    myzip.unzip();      // Can't do its job --> Exception
    delete("upd.zip");  // In case of exception: File would not be deleted here
}

int main() {
    try {
        Install();
    }
    catch (const Error& err) {
        delete("upd.zip"); // File must be deleted here
        MessageBox(err.text);
    }
}

Версия B (с повторным бросанием исключения)

void Install() {
    getFile("upd.zip"); // Creates File
    try {
        MyZip myzip("upd.zip");
        myzip.unzip();
    }
    catch (const Error& err) {
        delete("upd.zip");
        throw err; // Re-Throw the Error
    }
    delete("upd.zip");
}

int main() {
    try {
        Install();
    }
    catch (const Error& err) {
        MessageBox(err.text);
    }
}

Версия C (с кодом возврата)

void Install() {
    getFile("upd.zip"); // Creates File
    MyZip myzip("upd.zip");
    if (!myzip.unzip("upd.zip")) {
        delete("upd.zip");
        throw Error(myzip.geterror()); // what was the reason
    }
    delete("upd.zip");
}

int main() {
    // Same as in Version B
}

1 Ответ

3 голосов
/ 23 сентября 2010

Ни один из трех. Используйте RAII :

class FileGuard {
public:
    FileGurad(const std::string & filePath)
    : m_FilePath( filePath )
    {}

    ~FileGuard() {
        delete(m_FilePath); // must not throw an exception
    }
private:
    std::string m_FilePath;
};

Использование:

void Install() {
    guard FileGuard(getFile("upd.zip")); // Creates File; getFile should return the path where the file was created
    MyZip myzip("upd.zip");
    myzip.unzip();      // Can't do its job --> Exception
    // file will be deleted when guard goes out of scope (e.g. when an expection is thrown)
}

В качестве альтернативы вы можете иметь FileGuard call getFile в конструкторе. См. этот ответ (и другие к тому же вопросу) для получения дополнительной информации о размотке стека (особенно в порядке уничтожения).

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