2014-10-17 12 views
6

Sto cercando di eseguire il debug dell'applicazione utilizzando i catch-rethrows delle eccezioni. Il mio codice di gestione delle eccezioni è più lungo di alcuni dei blocchi che sto eseguendo il debug, ed è tutto copia-incolla.Come rendere il codice di eccezione DRY?

Esiste un modo migliore per esprimere ripetutamente il codice riportato di seguito? Sospetto che le macro siano la strada da percorrere qui, ma di solito evito le macro come la peste.

try { 
    // Code here... 
    } 
    catch (std::exception & e) 
    { 
    ErrorMsgLog::Log("Error", "std exception caught in " __func__ " " __FILE__ " " __LINE__, e.what()); 
    throw e; 
    } 
    catch (Exception & e) 
    { 
    ErrorMsgLog::Log("Error", "Builder exception caught in " __func__ " " __FILE__ " " __LINE__, e.Message); 
    throw e; 
    } 
    catch (...) 
    { 
    ErrorMsgLog::Log("Error", "Unknown exception caught in " __func__ " " __FILE__ " " __LINE__); 
    throw std::runtime_error ("Unknown Exception in " __func__ " " __FILE__ " " __LINE__); 
    } 
+2

'inoltrare' tutte le eccezioni a una funzione di modello? – user2485710

+4

Imposta 'Exception' un sottotipo di' std :: exception', proprio come qualsiasi altro tipo di eccezione sane. – rightfold

+0

1. Questo non è C++ 11. Non posso inoltrare. 2. L'eccezione è una classe Borland C++ Builder. Inoltre, anche se * solo * gestivo l'eccezione std ::, vorrei comunque allontanarmi dal copia-incolla di esso. – QuestionC

risposta

0

Il modo migliore per implementare questo è probabilmente l'utilizzo di macro. La definizione della macro è un po 'brutta, ma chiamare la macro sarà abbastanza semplice e non sarà necessario riorganizzare il codice. Ecco un esempio che mostra come si potrebbe implementare esso:

#define RUN_SAFE(code) try {\ 
    code\ 
    }\ 
    catch (std::exception & e)\ 
    {\ 
    ErrorMsgLog::Log("Error");\ 
    throw e;\ 
    }\ 
    catch (Exception & e)\ 
    {\ 
    ErrorMsgLog::Log("Error");\ 
    throw e;\ 
    }\ 
    catch (...)\ 
    {\ 
    ErrorMsgLog::Log("Error");\ 
    throw std::exception();\ 
    }\ 

int main(){ 
    RUN_SAFE(
    cout << "Hello World\n"; 
) 
} 

Se siete davvero irremovibile di non usare le macro, è possibile utilizzare il metodo suggerito da @juanchopanza e utilizzare una funzione di ordine superiore per il controllo che prende il codice come parametro. Questo approccio richiederà probabilmente di refactoring il codice un po 'però. Ecco come è possibile implementarlo:

void helloWorld(){ 
    cout << "Hello World\n"; 
} 

void runSafe(void (*func)()){ 
    try { 
     func(); 
    } 
    catch (std::exception & e) 
    { 
     ErrorMsgLog::Log("Error"); 
     throw e; 
    } 
    catch (Exception & e) 
    { 
     ErrorMsgLog::Log("Error"); 
     throw e; 
    } 
    catch (...) 
    { 
     ErrorMsgLog::Log("Error"); 
     throw std::exception(); 
    } 
} 

int main(){ 
    runSafe(helloWorld); 
} 
+0

Dato che stai usando C++, usa una 'std :: function' invece di un puntatore a funzione grezza. Utilizzare gli argomenti del modello per il tipo di argomento della funzione e il tipo di ritorno. –

Problemi correlati