Cómo documentar excepciones lanzadas en c # /. Net

139

Actualmente estoy escribiendo un pequeño marco que será utilizado internamente por otros desarrolladores dentro de la empresa.

Quiero proporcionar buena información de Intellisense, pero no estoy seguro de cómo documentar las excepciones lanzadas.

En el siguiente ejemplo:

public void MyMethod1()
{
    MyMethod2();

    // also may throw InvalidOperationException
}

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException

    // also may throw DivideByZeroException
}

Sé que el marcado para documentar excepciones es:

/// <exception cref="SomeException">when things go wrong.</exception>

Lo que no entiendo es cómo documentar las excepciones generadas por el código invocado MyMethod1() .

  • ¿Debo documentar las excepciones lanzadas por MyMethod2()
  • ¿Debo documentar las excepciones lanzadas por File.Open()?

¿Cuál sería la mejor manera de documentar posibles excepciones?

Arnold Zokas
fuente
44
Sé que esto no es exactamente lo que estabas preguntando (y esta es una pregunta muy antigua), pero Eric Lippert (desarrollador principal en el compilador de Microsoft C # y los equipos de diseño) escribió una publicación de blog sobre los 4 tipos de excepciones que creo que cada desarrollador debería pensar al escribir el código de manejo de excepciones: blogs.msdn.com/b/ericlippert/archive/2008/09/10/…
javajavajavajavajava
@javajavajavajavajava Gracias por el enlace, definitivamente vale la pena leerlo.
Arnold Zokas
Creo que esta es una pregunta válida porque no es obvio en absoluto cómo documentar adecuadamente las excepciones en C # y las vistas de 50K muestran que tampoco es obvio para mucha gente. La segunda respuesta más votada es muy útil, ya que muestra el uso de xmldocs existentes para documentar esto. Votación para reabrir. Esta razón cercana "basada en la opinión" está matando muchas preguntas de programación realmente muy útiles.
Alexei

Respuestas:

110

Debe documentar todas las excepciones que pueda generar su código, incluidas las de cualquier método que pueda llamar.

Si la lista se vuelve un poco grande, es posible que desee crear su propio tipo de excepción. Capture todos los que pueda encontrar dentro de su método, envuélvalos en su excepción y tírelos.

Otro lugar en el que es posible que desee hacerlo de esta manera es si su método está en la cara de su API. Al igual que una fachada simplifica múltiples interfaces en una sola interfaz, su API debería simplificar múltiples excepciones en una sola excepción. Facilita el uso de su código para las personas que llaman.


Para responder algunas de las inquietudes de Andrew (de los comentarios), hay tres tipos de excepciones: las que no conoce, las que conoce y no puede hacer nada, y las que conoce y puede hacer algo al respecto.

Los que no sabes de ti quieren dejar ir. Es el principio de fallar rápidamente: es mejor que su aplicación se bloquee que ingresar a un estado en el que podría terminar corrompiendo sus datos. El bloqueo le informará sobre lo que sucedió y por qué, lo que puede ayudar a eliminar esa excepción de la lista de "los que no conoce".

Las que conoce y de las que no puede hacer nada son excepciones como OutOfMemoryExceptions. En casos extremos, es posible que desee manejar excepciones como esta, pero a menos que tenga algunos requisitos bastante notables, los trata como la primera categoría: déjelos ir. ¿ Tiene que documentar estas excepciones? Se vería bastante tonto documentando OOM en cada método que actualiza un objeto.

Los que conoces y sobre los que puedes hacer algo son los que debes documentar y envolver.

Puede encontrar algunas pautas más sobre el manejo de excepciones aquí.


fuente
3
Debo admitir que esto no suena muy práctico. No puedo imaginar cuántas excepciones potenciales puede generar cualquier código al que pueda llamar, además hay cosas como OutOfMemoryException que no querrá atrapar y ajustar.
Andrew Hare
3
¿Su respuesta será buena, pero en realidad son dos respuestas que se contradicen? "documenta cada excepción que pueda generar tu código" y "Las que conoces y sobre las que puedes hacer algo son las que deberías documentar".
tymtam
2
@Tymek: No. La primera mitad respondió a la pregunta "cómo debo documentar las excepciones", la segunda parte señaló la respuesta evidentemente obvia a "qué excepciones debo documentar". El primero no implica que documente cada excepción que pueda ocurrir. Algunas personas son demasiado literales, lo que requiere la segunda mitad.
55
@Tymek Creo que su punto podría ser que si puede hacer algo al respecto, ¿por qué no hacer algo al respecto en lugar de volver a lanzarlo y documentarlo? Puede ser más veraz decir "Los que conoces que el código del cliente puede hacer algo al respecto". Esto elimina la contradicción, porque estas son las excepciones ideales para documentar.
mes
En cuanto a las excepciones que 'sueltas', siempre puedes atraparlas en algún nivel inferior que las registre o algo así. Ya sabes; simplemente haciendo una forma fácil de usar de dejar que el programa se bloquee.
Nyerguds
96

Debe usar la documentación xml estándar .

/// <exception cref="InvalidOperationException">Why it's thrown.</exception>
/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod1()
{
    MyMethod2();
    // ... other stuff here
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod2()
{
    System.IO.File.Open(somepath...);
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
public void MyMethod3()
{
    try
    {
        MyMethod2();
    }
    catch (DivideByZeroException ex)
    {
        Trace.Warning("We tried to divide by zero, but we can continue.");
    }
}

El valor de hacerlo de esta manera es que está proporcionando documentación de las excepciones conocidas que pueden ocurrir. Esta documentación está disponible en intellisense si está utilizando Visual Studio y puede recordarle a usted (u otros) más tarde las excepciones que puede esperar.

Desea especificar los tipos de excepción específicos, ya que puede manejar un tipo de excepción, mientras que otros tipos son el resultado de un problema grave y no pueden corregirse.

escalofríos42
fuente
1
¿Cómo es eso agregar valor? Por ejemplo, todas estas excepciones son derivaciones del tipo Excepción. Desde mi experiencia, no será práctico pensar en cualquier otro tipo de excepción que pueda generarse desde las otras API que se invocan dentro de sus métodos. Lo que quiero decir es que no deberíamos preocuparnos por ninguna excepción que se produzca a partir de un método que no sea que lleve información comercial.
Illuminati
77
@ShiranGinige tu experiencia es incorrecta.
Grozz
35

Puede facilitar su proceso de documentación mediante el uso de varios complementos excelentes. Uno de ellos es GhostDoc , un complemento gratuito para Visual Studio que genera comentarios de documentos XML. Además, si usa ReSharper , eche un vistazo al excelente complemento Agent Johnson para ReSharper, que agrega una opción para generar comentarios XML para las excepciones lanzadas.

Actualización: Parece que Agen Johnson no está disponible para R # 8, pago Excepcional para ReSharper como alternativa ...

Paso 1: GhostDoc genera el comentario XML (Ctrl-Shift-D), mientras que el complemento Agent Johnson para ReSharper sugiere documentar también la excepción:

paso 1

Paso 2: Use la tecla de acceso directo de ReSharper (Alt-Enter) para agregar también la documentación de excepción:

paso 2 http://i41.tinypic.com/osdhm

Espero que ayude :)

Igal Tabachnik
fuente
Los enlaces tinípicos están rotos.
ANeves
11

Por lo que entiendo, la intención de usar el elemento <exception> es usarlo al decorar métodos, no excepciones:

/// <summary>Does something!</summary>
/// <exception cref="DidNothingException">Thrown if nothing is actually done.</exception>
public void DoSomething()
{
// There be logic here
}

Las excepciones que pueden ser lanzadas por otros métodos que se llaman deben ser detectadas, manejadas y documentadas en esos métodos. Deben documentarse las excepciones que posiblemente pueda generar .NET, o las excepciones explícitamente generadas por su propio código.

En cuanto a ser más específico que eso, ¿tal vez pueda atrapar y lanzar sus propias excepciones personalizadas?

Daniel Schaffer
fuente
4

Parte del contrato para su método debe ser verificar que las condiciones previas sean válidas, por lo tanto:

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException
}

se convierte

/// <exception cref="FileNotFoundException">Thrown when somepath isn't a real file.</exception>
public void MyMethod2()
{
    FileInfo fi = new FileInfo( somepath );
    if( !fi.Exists )
    {
        throw new FileNotFoundException("somepath doesn't exists")
    }
    // Maybe go on to check you have permissions to read from it.

    System.IO.File.Open(somepath...); // this may still throw FileNotFoundException though
}

Con este enfoque, es más fácil documentar todas las excepciones que arrojas explícitamente sin tener que documentar también que OutOfMemoryException se puede lanzar, etc.

Rowland Shaw
fuente
1
No estoy seguro de cuál es el punto de esa verificación si solo va a duplicar la excepción que la Openllamada arrojaría de todos modos (sin mencionar, como observa, que hay una carrera y que la verificación no garantiza el éxito Open). .
Matt Enright
1
@MattEnright De acuerdo, pero he hecho esto un poco artificial para ilustrar el punto ...
Rowland Shaw
1

Debe documentar todas las excepciones que posiblemente pueda generar su método.

Para ocultar los detalles de implementación, trataría de manejar algunas excepciones de MyMethod2.

Podría considerar volver a utilizarlos, si no puede manejar o resolver la excepción. Principalmente empaquetado / envuelto en una excepción más significativa para la persona que llama.

GvS
fuente
1

De hecho, como ya se ha respondido, la forma de documentar las excepciones es utilizando comentarios XML.

Además de los complementos, también puede usar herramientas de análisis estático que se pueden integrar con TFS para asegurarse de tener documentadas las excepciones.

En los enlaces a continuación, puede ver cómo crear una regla personalizada para StyleCop para validar las excepciones generadas por sus métodos que se están documentando.

http://www.josefcobonnin.com/post/2009/01/11/Xml-Documentation-Comments-Exceptions-I.aspx http://www.josefcobonnin.com/post/2009/01/15/Xml-Documentation -Comentarios-Excepciones-II.aspx

Saludos.


fuente
0

Documente las excepciones esperadas en su método, en su ejemplo, le diría al usuario que ese método puede lanzar una excepción de archivo no encontrado.

Recuerde que es para informar a la persona que llama qué esperar para que pueda elegir cómo lidiar con eso.

Damien
fuente