Si un idioma es inherentemente compatible con las excepciones, entonces se prefiere lanzar excepciones y los clientes pueden detectar la excepción si no desean que se produzca un error. De hecho, los clientes de su código esperan excepciones y se encontrarán con muchos errores porque no verificarán los valores de retorno.
Hay algunas ventajas en el uso de excepciones si tiene una opción.
Messages
Las excepciones contienen mensajes de error legibles por el usuario que los desarrolladores pueden utilizar para la depuración o incluso mostrarlos a los usuarios si así lo desean. Si el código consumidor no puede manejar la excepción, siempre puede iniciar sesión para que los desarrolladores puedan revisar los registros sin tener que detenerse en cada otra traza para averiguar cuál era el valor de retorno y mapearlo en una tabla para averiguar cuál era la excepción real.
Con los valores de retorno, no hay información adicional que pueda proporcionarse fácilmente. Algunos idiomas admitirán realizar llamadas de método para obtener el último mensaje de error, por lo que esta preocupación se alivia un poco, pero eso requiere que la persona que llama realice llamadas adicionales y, a veces, requerirá acceso a un "objeto especial" que transporta esta información.
En el caso de los mensajes de excepción, proporciono la mayor cantidad de contexto posible, como por ejemplo:
No se pudo recuperar una política del nombre "foo" para la "barra" del usuario, a la que se hizo referencia en el perfil del usuario.
Compare esto con un código de retorno -85. ¿Cuál preferirías?
Pila de llamadas
Las excepciones generalmente también tienen pilas de llamadas detalladas que ayudan a depurar el código más rápido y más rápido, y también pueden ser registradas por el código de llamada, si así lo desea. Esto permite que los desarrolladores identifiquen el problema generalmente en la línea exacta, y por lo tanto es muy poderoso. Una vez más, compare esto con un archivo de registro con valores de retorno (como un -85, 101, 0, etc.), ¿cuál preferiría?
Falla en el enfoque sesgado rápido
Si se llama a un método en algún lugar que falla, lanzará una excepción. El código de llamada debe suprimir explícitamente la excepción o fallará. Descubrí que esto es realmente sorprendente porque durante el desarrollo y las pruebas (e incluso en la producción) el código falla rápidamente, lo que obliga a los desarrolladores a solucionarlo. En el caso de los valores de retorno, si se omite una verificación de un valor de retorno, el error se ignora silenciosamente y el error aparece en algún lugar inesperado, generalmente con un costo mucho mayor de depuración y corrección.
Empaquetado y desempaquetado de excepciones
Las excepciones se pueden ajustar dentro de otras excepciones y luego se pueden desempaquetar si es necesario. Por ejemplo, su código podría lanzar ArgumentNullException
que el código de llamada podría incluir dentro de UnableToRetrievePolicyException
porque esa operación falló en el código de llamada. Si bien al usuario se le puede mostrar un mensaje similar al ejemplo que proporcioné anteriormente, algunos códigos de diagnóstico podrían desenvolver la excepción y descubrir que un ArgumentNullException
causó el problema, lo que significa que es un error de codificación en el código del consumidor. Esto podría disparar una alerta para que el desarrollador pueda corregir el código. Tales escenarios avanzados no son fáciles de implementar con los valores de retorno.
Simplicidad de código
Este es un poco más difícil de explicar, pero aprendí a través de esta codificación, tanto con valores de retorno como con excepciones. El código que se escribió usando valores de retorno usualmente haría una llamada y luego tendría una serie de verificaciones sobre cuál era el valor de retorno. En algunos casos, llamaría a otro método, y ahora tendrá otra serie de comprobaciones para los valores de retorno de ese método. Con excepciones, el manejo de excepciones es mucho más simple en la mayoría, si no en todos los casos. Tiene un bloque try / catch / finally, con el tiempo de ejecución haciendo todo lo posible para ejecutar el código en los bloques finally para la limpieza. Incluso los bloques de prueba / captura / finalmente anidados son relativamente más fáciles de seguir y mantener que los valores anidados si / else y los valores de retorno asociados de múltiples métodos.
Conclusión
Si la plataforma que está utilizando admite excepciones (especialmente, como Java o .NET), entonces definitivamente no debe asumir que no hay otra forma, excepto para lanzar excepciones porque estas plataformas tienen pautas para lanzar excepciones, y sus clientes lo van a esperar así. Si estuviera usando su biblioteca, no me molestaré en verificar los valores de retorno porque espero que se produzcan excepciones, así es como está el mundo en estas plataformas.
Sin embargo, si fuera C ++, sería un poco más difícil de determinar porque ya existe una base de código grande con códigos de retorno, y una gran cantidad de desarrolladores están sintonizados para devolver valores en lugar de excepciones (por ejemplo, Windows está lleno) con HRESULTs). Además, en muchas aplicaciones, también puede ser un problema de rendimiento (o al menos se percibe que es).