En esta pregunta más reciente hice hincapié en que las excepciones no deberían contener ningún mensaje. En mi opinión, el hecho de que lo hagan es un gran error. Lo que estoy proponiendo es que
El "mensaje" de la excepción es el nombre de clase (completamente calificado) de la excepción.
Una excepción debe contener dentro de sus propias variables miembro tantos detalles como sea posible acerca de lo que sucedió; por ejemplo, un IndexOutOfRangeException
debe contener el valor de índice que se encontró que no es válido, así como los valores superior e inferior que eran válidos en el momento en que se lanzó la excepción. De esta manera, utilizando la reflexión, puede hacer que se construya automáticamente un mensaje que lea así: IndexOutOfRangeException: index = -1; min=0; max=5
y esto, junto con el seguimiento de la pila, debe ser toda la información objetiva que necesita para solucionar el problema. Formatearlo en un mensaje bonito como "el índice -1 no estaba entre 0 y 5" no agrega ningún valor.
En su ejemplo particular, la clase NodePropertyNotFoundException
contendría el nombre de la propiedad que no se encontró y una referencia al nodo que no contenía la propiedad. Esto es importante: debe no contener el nombre del nodo; debe contener una referencia al nodo real. En su caso particular, esto puede no ser necesario, pero es una cuestión de principios y una forma de pensar preferida: la principal preocupación al construir una excepción es que debe ser utilizable por código que pueda atraparla. La usabilidad por parte de los humanos es una preocupación importante, pero solo secundaria.
Esto se encarga de la muy frustrante situación que pudo haber presenciado en algún momento de su carrera, en el que pudo haber detectado una excepción que contiene información vital sobre lo que sucedió dentro del texto del mensaje, pero no dentro de sus variables miembro , por lo que tuvo que hacer un análisis de cadena del texto para averiguar qué sucedió, esperando que el texto del mensaje se mantuviera igual en las versiones futuras de la capa subyacente, y rezando para que el texto del mensaje no esté en algún idioma extranjero cuando su programa se ejecuta en otros países.
Por supuesto, dado que el nombre de clase de la excepción es el mensaje de la excepción (y las variables miembro de la excepción son los detalles específicos), esto significa que necesita muchas y muchas excepciones diferentes para transmitir todas las diferentes mensajes, y eso está bien.
Ahora, a veces, mientras escribimos código, nos encontramos con una situación errónea por la cual solo queremos codificar rápidamente una declaración throw
y continuar escribiendo nuestro código en lugar de tener que interrumpir lo que estamos haciendo para crear una nueva clase de excepción para que podamos tirar allí. Para estos casos, tengo una clase GenericException
que de hecho acepta un mensaje de cadena como un parámetro de tiempo de construcción, pero el constructor de esta clase de excepción está adornado con un gran gran gran púrpura brillante FIXME XXX TODO
comentario que indica que cada uno la creación de instancias de esta clase debe reemplazarse con una instanciación de alguna clase de excepción más especializada antes de que se lance el sistema de software, preferiblemente antes de que se confirme el código.