Diseño de jerarquía de excepción

9

En mi empresa, estamos construyendo una aplicación web que contiene varios servicios centrales que diseñamos nosotros mismos y luego especificamos como interfaces. Es decir, las interfaces son específicas de la aplicación y luego se implementan con bibliotecas de terceros que podemos cambiar con el tiempo. Cuando se trata de excepciones, me he dado cuenta de que las excepciones lanzadas por nuestros servicios deberían ser nuestras propias excepciones específicas de la aplicación en lugar de las excepciones específicas de la implementación.

Ahora, me pregunto cómo deberían estructurarse y relacionarse nuestras excepciones.

Primero, considere una excepción genérica MyAppException. Esta excepción indica que algo inesperado salió mal y lo mejor que podemos hacer es mostrar un mensaje al usuario diciendo que algo salió mal y que estamos trabajando en ello. El error podría ser que la base de datos se bloqueó o algo similar. Esta excepción se lanzaría prácticamente desde todos los métodos que trabajan con la base de datos.

En segundo lugar, considere una excepción MyAppDuplicateException. Esta excepción indicaría que el usuario intentó guardar algo en la base de datos que ya estaba allí. Aquí, podemos mostrar un mensaje de error mucho más específico y esta excepción solo se genera desde los métodos que insertan o actualizan las filas de la base de datos.

La aplicación también puede contener otras excepciones similares a MyAppDuplicateExceptionotras situaciones de error esperadas. Ex MyAppNotFoundExceptionetc ...

Ahora a mis preguntas:

  1. ¿Deberían extenderse las otras excepciones MyAppException? En realidad no veo ninguna razón para esto, lo acabo de ver en muchos lugares y me pregunto si tiene un propósito. La desventaja de esto, como lo veo, es que una declaración try / catch no necesita preocuparse por la excepción específica en este caso. Simplemente puede detectar la excepción principal y, debido a esto, no necesita manejar el error específico, que era prácticamente el punto de tener la excepción específica.
  2. Si las otras excepciones no se extienden MyAppException, ¿debería MyAppExceptionser un java.lang.RuntimeException? Esto no requeriría el código de ejecución para atraparlo, lo que para mí suena natural ya que el punto de la excepción es decir que sucedió algo desconocido y no se espera que el código de ejecución pueda manejarlo. El código en el punto de entrada de la solicitud aún podría tener una declaración try / catch que detecta MyAppExceptiony asegura que se muestra un mensaje al usuario.

editar No hay duda de si las excepciones específicas como MyAppDuplicateExceptiondeberían verificarse o no, deberían verificarse definitivamente.

Ludwig Magnusson
fuente

Respuestas:

9
  1. A veces desea capturar un tipo específico de excepción (por ejemplo MyAppDuplicateException) y, a veces, desea capturar una categoría completa de excepciones (por ejemplo MyAppException). Al MyAppDuplicateExceptionextender, MyAppExceptionle está dando al código de llamada un poco más de flexibilidad en la forma en que maneja las diferentes excepciones.
  2. El mejor consejo que he escuchado sobre esto es que, en términos generales , debe lanzar una excepción marcada si lo que se llama su método obedeció su contrato. Es una forma de decir "aquí están las cosas que se podría esperar que fallen". Definitivamente haría MyAppDuplicateExceptiony las excepciones marcadas similares (es decir, no RuntimeException s).

Hay un artículo muy bueno aquí lo que debería ayudar a evitar la mayor parte de los problemas más comunes.

vaughandroid
fuente
Veo su punto con nr 1. Sin embargo, es mi experiencia que nunca nos encontramos con la situación en la que queremos obtener todo tipo de excepciones de nuestros servicios. Si algo sale mal, realmente queremos saber exactamente qué es. Lo que escucho de su segundo punto es que MyAppException debería ser RuntimmeException. (los demás deben verificarse, no hay duda al respecto)
Ludwig Magnusson
@vaughandroid, el enlace está roto. Aquí está el archivo: community.oracle.com/docs/DOC-983543
user167569
@ user167569 Gracias por el aviso. Han arreglado el enlace.
vaughandroid
@LudwigMagnusson # 1 muestra el problema cuando desea detectar una rama de excepciones en un determinado momento, posiblemente después de manejar otras más específicas. Eso no es lo mismo que atrapar todas las excepciones. El problema con el n. ° 2 es el contexto. Se podría decir que una IOExceptiondebería ser una excepción de tiempo de ejecución para Archivo no encontrado si el archivo es un recurso que debería estar allí. Sin embargo, es una excepción comprobada en el caso de que un usuario solicite un nombre de archivo específico que puede existir o no. Esto es especialmente cierto cuando se crean bibliotecas para las cuales el contexto no se conoce de antemano.
Maarten Bodewes
1

Me he dado cuenta de que las excepciones lanzadas por nuestros servicios deberían ser nuestras propias excepciones específicas de la aplicación en lugar de las excepciones específicas de la implementación .

¿Con esto quiere decir excepciones definidas por su implementación de terceros? ¿Correcto?

Primero, considere una excepción genérica MyAppException. Esta excepción indica que> algo inesperado salió mal y lo mejor que podemos hacer es> mostrarle un mensaje al usuario diciendo que algo salió mal y que> estamos trabajando en ello. El error podría ser que la base de datos se bloqueó o algo similar. Esta excepción se lanzaría prácticamente desde todos los métodos que trabajan> con la base de datos.

Si este tipo de excepción representa un error en su programa que no es causado por una entrada incorrecta del usuario, sino por algún problema con su código, entonces en Java debería ser una excepción en tiempo de ejecución.

En segundo lugar, considere una excepción MyAppDuplicateException. Esta excepción indicaría que el usuario intentó guardar algo en la base de datos que ya estaba allí. Aquí, podemos mostrar un mensaje de error mucho más específico y esta> excepción solo se genera desde los métodos que insertan o actualizan las bases de datos> filas.

Esta es una excepción comprobada en Java.

Si las otras excepciones no extienden MyAppException, ¿MyAppException> debería ser una java.lang.RuntimeException?

Si.

Esto no requeriría el código de ejecución para atraparlo, lo que para mí suena natural> ya que el punto de la excepción es decir que sucedió algo desconocido y> no se espera que el código de ejecución pueda manejarlo. El código en el> punto de entrada de la solicitud aún podría tener una declaración try / catch que captura> MyAppException y se asegura de que se muestre un mensaje al usuario.

Si eso es correcto.

usuario48910
fuente
Me entiendes correctamente.
Ludwig Magnusson
Cuando dice que el error es causado por "un problema con mi código", solo quiero señalar que el problema también podría estar relacionado con la conexión de la base de datos, etc. No solo con errores en la programación.
Ludwig Magnusson