No creo que las capturas locales sean un antipatrón, de hecho, si recuerdo correctamente, ¡en realidad se aplica en Java!
Lo que es clave para mí al implementar el manejo de errores es la estrategia general. Es posible que desee un filtro que capture todas las excepciones en el límite del servicio, puede interceptarlas manualmente; ambas están bien siempre que haya una estrategia general que se ajuste a los estándares de codificación de sus equipos.
Personalmente, me gusta detectar errores dentro de una función cuando puedo hacer uno de los siguientes:
- Agregue información contextual (como el estado de los objetos o lo que estaba sucediendo)
- Maneje la excepción de forma segura (como un método TryX)
- Su sistema está cruzando un límite de servicio y está llamando a una biblioteca externa o API
- Desea capturar y volver a lanzar un tipo diferente de excepción (quizás con el original como excepción interna)
- La excepción se lanzó como parte de alguna funcionalidad de fondo de bajo valor
Si no es uno de estos casos, no agrego un try / catch local. Si es así, dependiendo del escenario, puedo manejar la excepción (por ejemplo, un método TryX que devuelve un falso) o volver a lanzar para que la estrategia global maneje la excepción.
Por ejemplo:
public bool TryConnectToDatabase()
{
try
{
this.ConnectToDatabase(_databaseType); // this method will throw if it fails to connect
return true;
}
catch(Exception ex)
{
this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
return false;
}
}
O un ejemplo de repensar:
public IDbConnection ConnectToDatabase()
{
try
{
// connect to the database and return the connection, will throw if the connection cannot be made
}
catch(Exception ex)
{
this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
throw;
}
}
Luego, detecta el error en la parte superior de la pila y presenta un mensaje agradable al usuario.
Independientemente del enfoque que adopte, siempre vale la pena crear pruebas unitarias para estos escenarios para que pueda asegurarse de que la funcionalidad no cambie e interrumpa el flujo del proyecto en una fecha posterior.
No ha mencionado en qué idioma está trabajando, pero es un desarrollador de .NET y lo ha visto demasiadas veces sin mencionarlo.
NO ESCRIBA:
catch(Exception ex)
{
throw ex;
}
Utilizar:
catch(Exception ex)
{
throw;
}
¡El primero restablece el rastro de la pila y hace que su nivel superior de captura sea completamente inútil!
TLDR
La captura local no es un antipatrón, a menudo puede ser parte de un diseño y puede ayudar a agregar contexto adicional al error.