Domanda

Qual è il posto giusto per spiegare la gestione degli errori in un'istruzione try-catch? Sembra che potresti inserire commenti esplicativi all'inizio del blocco try o del blocco catch.

// Possible comment location 1
try
{   
    // real code
}
// Possible comment location 2
catch
{
    // Possible comment location 3

    // Error handling code

}
È stato utile?

Soluzione

Di solito faccio quanto segue. Se viene gestita solo un'eccezione, di solito non mi preoccupo poiché dovrebbe essere auto-documentante.

try
{   
    real code // throws SomeException
    real code // throws SomeOtherException
}
catch(SomeException se)
{
    // explain your error handling choice if it's not obvious
}
catch(SomeOtherException soe)
{
    // explain your error handling choice if it's not obvious
}

Altri suggerimenti

" Un commento è una bugia " . Lavora su quei nomi di variabili e sulla logica generale in modo da poterlo evitare. E se hai davvero bisogno di mentire, fallo all'interno del blocco di cattura.

Non credo che sia importante.

Penso che la cosa importante da ricordare con i commenti sia quella di affrontare perché il codice è come è e non cosa sta facendo il codice, prima di tutto. Questo non vuol dire che non dovresti spiegare una logica complessa in un commento conciso, ma il perché è molto più importante.

Che ne dici di impostare il codice in modo che non abbia bisogno di commenti extra?

try
{ 
   performDifficultAct( parameter );
}
catch (ArgumentOutOfRangeException couldNotFindArgument)
{
   // handle exception
}
catch (Exception otherUnknownException )
{
   // handle exception
}

Non è necessario documentare se è possibile utilizzare la variabile e la denominazione del metodo per mostrare cosa sta succedendo. Non è necessario documentare se si deve registrare o aumentare le eccezioni: il messaggio di registrazione nel codice sorgente dovrebbe comunque essere autoesplicativo. L'unica volta in cui dovresti aver bisogno di ulteriore documentazione nel tuo codice è quando non è del tutto ovvio ciò che il codice sta facendo o c'è un gotcha facile da perdere o un passo ambiguo che devi aggiungere che avrà bisogno di spiegazioni per chiunque guardi il codice in futuro.

Modifica: per chiarire un po ', ecco un po' di più su come potrei usare quelle "cattura" dichiarazioni per fornire informazioni utili sia a un programmatore di manutenzione che agli utenti / supporto / QA / chiunque altro utilizzi il software. Anche un'illustrazione del tipo di situazione in cui vorrei assolutamente aggiungere ulteriori commenti nel codice:

public void PerformSomeActionOrOther(string parameter)
{
  try
  { 
     // For some reason an eleven character string causes a bluescreen from Kernel32
     if (parameter.Length==11) parameter+=" ";

     performDifficultAct( parameter );
  }
  catch (ArgumentOutOfRangeException couldNotFindArgument)
  {
     this.Log.WriteLn("Argument out of range exception in ArbitraryClass.PerformSomeActionOrOther");
     this.Log.WriteLn(String.Format("Probable cause is that {0} is not in the array", parameter));
     this.Log.WriteLn(String.Format("Exception: {0}", couldNotFindArgument.Message));
  }
  catch (Exception otherUnknownException )
  {
     this.Log.WriteLn("Unexpected exception in ArbitraryClass.PerformSomeActionOrOther");
     this.Log.WriteLn(String.Format("Exception: {0}", otherUnknownException.Message));
     throw( otherUnknownException );
  }
}

Sicuramente non commentare la parte superiore di esso, perché cosa puoi utilmente dire se non "avviare un blocco di gestione delle eccezioni qui"? I commenti sulle dichiarazioni di cattura sono migliori, ma in generale, ancora una volta, cosa dirai? " Gestisci una NullPointerException " ;?

Vorrei un commento IFF che devi dire che stai facendo qualcosa di eccitante, come concatenare un'eccezione nel dominio dell'applicazione.

Penso che un tentativo / cattura ben scritto dovrebbe essere conciso e specifico. Concordo con @Jason sul fatto che il perché sia più importante ma, allo stesso modo, è importante mantenere il codice interno il più conciso possibile.

Sarebbe anche utile se venissero utilizzate eccezioni specifiche. Se ad esempio stai usando Java, prova a catturare una NullPointerException anziché un'eccezione generica. Questo dovrebbe spiegare perché esiste il tentativo di cattura e cosa stai facendo per risolverlo.

La posizione non ha importanza purché tu sia coerente. La mia preferenza personale è la seguente:

//comment 1: code does XYZ, can cause exceptions A, B, C
try {
    //do something
}
//comment 2: exception A occurs when foo != bar
catch (ExceptionA a) {
    //do something
}
//comment 3: exception B occurs when bar is null
catch (ExceptionB b) {
    //do something
}
//comment 4: exception B occurs when foo is null
catch (ExceptionC c) {
    //do something
}

So che questa non è la risposta che stai cercando, ma non commentare affatto. Se il tuo codice non è abbastanza chiaro per essere autonomo senza commentare, dovresti rifattorizzarlo fino a quando non lo è. Jeffrey Palerm o ha appena scritto un post di blog che lo afferma meglio.

In genere, i commenti tendono a documentare:

  • Codice troppo compatto. Cose che assomigliano a questo: ++i?--g:h-i;
  • Lunghi blocchi di codice che devono essere riassunti
  • Codice usa e getta o non ha motivi chiari per l'esistenza

Vedi sotto per un esempio semplificato di alcuni semplici commenti sul blocco delle eccezioni e una versione che elimina la necessità di commenti.

bool retries = 0;
while (retries < MAX_RETRIES)
{
    try
    {
        ... database access code
        break;
    }
    // If under max retries, log and increment, otherwise rethrow
    catch (SqlException e)
    {
        logger.LogWarning(e);
        if (++retries >= MAX_RETRIES)
        {
            throw new MaxRetriesException(MAX_RETRIES, e);
        }
    }
    // Can't retry.  Log error and rethrow.
    catch (ApplicationException e)
    {
        logger.LogError(e);
        throw;
    }
}

Mentre i commenti precedenti promuovono la riusabilità, in sostanza devi mantenere sia il codice che i commenti. È possibile (e preferibile) riformattare questo in modo che sia più chiaro senza commenti.

bool retries = 0;
while (canRetry(retries))
{
    try
    {
        ... database access code
        break;
    }
    catch (SqlException e)
    {
        logger.LogWarning(e);
        retries = incrementRetriesOrThrowIfMaxReached(retries, e);
    }
    catch (ApplicationException e)
    {
        logger.LogError(e);
        throw;
    }
}

...

private void incrementRetriesOrThrowIfMaxReached(int retries, Exception e)
{
    if (++retries >= MAX_RETRIES)
        throw new MaxRetriesException(MAX_RETRIES, e);

    return retries;
}

private bool canRetry(int retries)
{
    return retries < MAX_RETRIES;
}

Il secondo esempio può sembrare più codice per un vantaggio molto sottile, ma i guadagni non possono essere sopravvalutati. Il codice è altrettanto comprensibile, ma hai il vantaggio di non avere bisogno di un set separato di metadati (commenti) per spiegare il codice. Il codice si spiega da solo. Se il blocco del codice di cattura è troppo lungo e necessita di un commento per riassumere, pensa a rifattorizzarlo in un metodo separato per migliorare la leggibilità.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top