Frequenza di gestione delle eccezioni / Dettaglio registro

6

Sto lavorando su un'applicazione .NET piuttosto complessa che interagisce con un'altra applicazione. Molte dichiarazioni a riga singola sono possibili colpevoli per aver lanciato un'eccezione e spesso non c'è nulla che io possa fare per verificare lo stato prima di eseguirlo per evitare queste eccezioni.

La domanda è, sulla base delle migliori pratiche e dell'esperienza esperta, con quale frequenza dovrei allacciare il mio codice con i blocchi try / catch? Ho elencato tre esempi di seguito, ma sono aperto a qualsiasi consiglio.

Spero davvero di ottenere alcuni pro / contro di vari approcci. Riesco sicuramente a crearne alcune (granularità del registro maggiore per l'approccio O-C, prestazioni migliori per l'approccio Monolithic), quindi cerco esperienza sull'opinione.

EDIT: dovrei aggiungere che questa applicazione è un programma batch. L'unico "recupero" necessario nella maggior parte dei casi è quello di registrare l'errore, pulire con garbo e uscire. Quindi questo potrebbe essere visto come una questione di granularità del registro come gestione delle eccezioni. Nella mia mente posso immaginare buone ragioni per entrambi, quindi sto cercando alcuni consigli generali per aiutarmi a trovare un equilibrio appropriato.

Approccio monolitico

class Program{
    public static void Main(){
        try{
            Step1();
            Step2();
            Step3();
        } catch (Exception e) {
            Log(e);
        } finally {
            CleanUp();
        }
    }

    public static void Step1(){
        ExternalApp.Dangerous1();
        ExternalApp.Dangerous2();
    }

    public static void Step2(){
        ExternalApp.Dangerous3();
        ExternalApp.Dangerous4();
    }

    public static void Step3(){
        ExternalApp.Dangerous5();
        ExternalApp.Dangerous6();
    }
}

Approccio delegato

class Program{
    public static void Main(){
        try{
            Step1();
            Step2();
            Step3();
        } finally {
            CleanUp();
        }
    }

    public static void Step1(){
        try{
            ExternalApp.Dangerous1();
            ExternalApp.Dangerous2();
        } catch (Exception e) {
            Log(e);
            throw;
        }
    }

    public static void Step2(){
        try{
            ExternalApp.Dangerous3();
            ExternalApp.Dangerous4();
        } catch (Exception e) {
            Log(e);
            throw;
        }
    }

    public static void Step3(){
        try{
            ExternalApp.Dangerous5();
            ExternalApp.Dangerous6();
        } catch (Exception e) {
            Log(e);
            throw;
        }
    }
}

Approccio ossessivo-compulsivo

class Program{
    public static void Main(){
        try{
            Step1();
            Step2();
            Step3();
        } finally {
            CleanUp();
        }
    }

    public static void Step1(){
        try{
            ExternalApp.Dangerous1();
        } catch (Exception e) {
            Log(e);
            throw;
        }
        try{
            ExternalApp.Dangerous2();
        } catch (Exception e) {
            Log(e);
            throw;
        }
    }

    public static void Step2(){
        try{
            ExternalApp.Dangerous3();
        } catch (Exception e) {
            Log(e);
            throw;
        }
        try{
            ExternalApp.Dangerous4();
        } catch (Exception e) {
            Log(e);
            throw;
        }
    }

    public static void Step3(){
        try{
            ExternalApp.Dangerous5();
        } catch (Exception e) {
            Log(e);
            throw;
        }
        try{
            ExternalApp.Dangerous6();
        } catch (Exception e) {
            Log(e);
            throw;
        }
    }
}

Altri approcci apprezzati e incoraggiati. Sopra sono solo degli esempi.

    
posta JDB 02.11.2012 - 19:44
fonte

3 risposte

12

Catch alla granularità che è significativa per la tua applicazione. Se non hai intenzione di intraprendere un'azione diversa per un'altra fonte di eccezioni, non c'è bisogno di rompere queste cose.

    
risposta data 02.11.2012 - 19:51
fonte
4

Preferisco l'approccio uno.

Le eccezioni aumenteranno lo stack di chiamate fino al blocco try/catch nel metodo main e verranno comunque registrate.

Non catch nei tuoi metodi step a meno che tu non sia in grado di gestire ogni eccezione localmente in qualche modo.

    
risposta data 02.11.2012 - 19:54
fonte
3

Chiediti perché la sintassi dell'eccezione è stata inventata quando è perfettamente possibile gestire condizioni impreviste senza di esse. In C, tutto il codice assomiglia al tuo approccio ossessivo-compulsivo, tranne che per il blocco try/catch , il valore restituito dalla funzione indica il successo o il fallimento.

Il motivo per cui sono state inventate le eccezioni è di consentire al codice di assomigliare al tuo approccio monolitico. È molto più pulito, segue il principio ASCIUTTO ed è più facile che le persone scrivano i livelli inferiori senza imporre rigide regole sulla gestione delle eccezioni in ogni singola funzione. Questa dovrebbe essere la modalità operativa predefinita e dovresti anche rilevare le eccezioni solo nei livelli inferiori se puoi effettivamente recuperare dall'errore, non solo segnalarlo.

    
risposta data 02.11.2012 - 20:09
fonte