Pregunta

¿Cuál es el lugar adecuado para explicar el manejo de errores en una declaración try-catch? Parece que puedes poner comentarios explicativos al principio del bloque try o al bloque catch.

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

    // Error handling code

}
¿Fue útil?

Solución

Normalmente hago lo siguiente. Si solo se maneja una excepción, normalmente no me molesto, ya que debería ser autodocumentada.

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
}

Otros consejos

" Un comentario es una mentira " . Trabaja en esos nombres de variables y la lógica general para que puedas evitarlo. Y si realmente necesitas mentir, hazlo dentro del bloque catch.

No creo que importe en absoluto.

Creo que lo importante para recordar con comentarios es abordar por qué el código es la forma en que se encuentra y no lo que hace el código, en primer lugar. Esto no quiere decir que no deba explicar la lógica compleja en un comentario conciso, pero el por qué es mucho más importante.

¿Qué hay de configurar el código para que no necesite comentarios adicionales?

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

No es necesario que documente si puede usar la variable y el nombre de su método para mostrar lo que está sucediendo. No es necesario documentar si tiene que iniciar sesión o generar las excepciones: el mensaje de registro en el código fuente debe explicarse por sí solo de todos modos. La única vez que necesite documentación adicional en su código es cuando no está claro qué está haciendo el código o si hay un paso fácil o un error ambiguo que debe agregar, que necesitará una explicación para quien mire el código en el futuro.

Editar: para aclarar un poco, aquí hay un poco más de cómo puedo usar esos " captura " declaraciones para proporcionar información útil tanto a un programador de mantenimiento como a usuarios / soporte / QA / cualquier otra persona que use el software. También una ilustración del tipo de situación en la que me gustaría agregar comentarios adicionales en el código:

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 );
  }
}

Definitivamente no comentes la parte superior, porque ¿qué puedes decir útilmente, excepto que "comenzar un bloque de manejo de excepciones aquí"? Los comentarios sobre las declaraciones de captura son mejores, pero en general, de nuevo, ¿qué vas a decir? " Manejar una NullPointerException " ;?

Iría a hacer un comentario IFF, debes decir que estás haciendo algo emocionante, como encadenar a una excepción de dominio de aplicación.

Creo que un try / catch bien escrito debe ser conciso y específico. Estoy de acuerdo con @Jason en que el por qué es más importante pero, igualmente, es importante que el código sea lo más conciso posible.

También ayudaría si utilizara excepciones específicas para ser capturado. Por ejemplo, si está utilizando Java, intente capturar una NullPointerException en lugar de una excepción genérica. Esto debería explicar por qué existe el try catch y qué está haciendo para resolverlo.

La ubicación no importa siempre que seas consistente. Mi preferencia personal es la siguiente:

//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
}

Sé que esta no es la respuesta que estás buscando, pero no hagas ningún comentario. Si su código no es lo suficientemente claro como para sostenerse por sí solo sin comentar, debe refactorizarlo hasta que lo sea. Jeffrey Palerm o simplemente escribió un publicación de blog que lo indica mejor.

Por lo general, los comentarios tienden a documentar:

  • Código que es demasiado compacto. Cosas que se ven así: ++i?--g:h-i;
  • Bloques largos de código que deben resumirse
  • El código es desechable o no tiene una razón clara para existir

Vea a continuación un ejemplo simplificado de algunos comentarios simples sobre su bloque de excepción, y una versión que elimina la necesidad de comentarios.

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;
    }
}

Si bien los comentarios anteriores promueven la reutilización, esencialmente debe mantener tanto el código como los comentarios. Es posible (y preferible) refactorizar esto para que sea más claro sin comentarios.

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;
}

El último ejemplo puede parecer más código para un beneficio muy sutil, pero las ganancias no pueden ser exageradas. El código es igual de comprensible, pero tiene la ventaja de que no necesita tener un conjunto separado de metadatos (comentarios) para explicar el código. El código se explica por sí mismo. Si su bloque de código de captura es demasiado largo y necesita comentarios para resumir, piense en refactorizarlo a un método separado para mejorar la legibilidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top