Regla
Manejar errores en captura bloques.
Vacío catch vacíos en silencio se tragan errores,
haciendo depuración la depuración.
Lenguajes soportados: Java, C, C++, PHP, JavaScript,
TypeScript, Go, PythonIntroducción
Los bloques catch vacíos son uno de los anti-patrones más peligrosos en código de producción. Cuando las excepciones son capturadas pero no manejadas, el error desaparece sin dejar rastro. La aplicación continúa ejecutándose con un estado corrupto, datos inválidos u operaciones fallidas que deberían haber detenido la ejecución. Los usuarios experimentan fallos silenciosos donde las funcionalidades no operan, pero no reciben mensajes de error. Los equipos de operaciones no tienen registros con los que depurar. La única indicación de que algo va mal aparece horas o días después, cuando los fallos en cascada hacen que el sistema sea inutilizable.
Por qué es importante
Depuración y respuesta a incidentes: Los bloques `catch` vacíos eliminan los registros de errores. Los ingenieros no tienen un seguimiento de pila, mensaje de error o indicación de cuándo o dónde ocurrió el fallo, lo que hace que los problemas sean casi imposibles de reproducir.
Corrupción silenciosa de datos: Cuando las operaciones de base de datos o las llamadas a la API fallan dentro de bloques `catch` vacíos, la aplicación continúa como si hubieran tenido éxito. Los registros se actualizan parcialmente, las transacciones quedan incompletas y, cuando se descubre la corrupción, el rastro de auditoría ha desaparecido.
Vulnerabilidades de seguridad: Los bloques catch vacíos ocultan fallos de seguridad como errores de autenticación o comprobaciones de autorización. Un atacante que desencadena una excepción en una ruta crítica para la seguridad podría eludir por completo las protecciones si el error es silenciado.
Fallos en cascada: Cuando los errores se ocultan, la aplicación continúa en un estado inválido. Las operaciones subsiguientes que dependen del resultado de la operación fallida también fallarán, creando una cadena de fallos que desvía a los ingenieros de la causa raíz real.
Ejemplos de código
❌ No conforme:
async function updateUserProfile(userId, profileData) {
try {
await db.users.update(userId, profileData);
await cache.invalidate(`user:${userId}`);
await searchIndex.update(userId, profileData);
} catch (error) {
// TODO: handle error
}
return { success: true };
}Por qué está mal: Si alguna operación falla, el error se ignora silenciosamente y la función devuelve éxito. La base de datos podría actualizarse, pero la invalidación de la caché podría fallar, dejando datos obsoletos. O la actualización del índice de búsqueda falla, haciendo que el usuario no sea localizable, sin un registro o alerta que indique el problema.
✅ Conforme:
async function updateUserProfile(userId, profileData) {
try {
await db.users.update(userId, profileData);
await cache.invalidate(`user:${userId}`);
await searchIndex.update(userId, profileData);
return { success: true };
} catch (error) {
logger.error('Failed to update user profile', {
userId,
error: error.message,
stack: error.stack
});
throw new ProfileUpdateError(
'Unable to update profile',
{ cause: error }
);
}
}
Por qué esto es importante: Cada error se registra con contexto, proporcionando información de depuración. El error se propaga al llamador, permitiendo un manejo de errores adecuado en el nivel apropiado. Los sistemas de monitorización pueden alertar sobre estos errores, y la aplicación falla rápidamente en lugar de continuar con un estado inválido.
Conclusión
Los bloques catch vacíos nunca son aceptables en código de producción. Toda excepción capturada necesita ser registrada como mínimo, y la mayoría deben propagarse a los llamadores o desencadenar acciones de recuperación específicas. Si realmente necesita ignorar un error, documente el motivo con un comentario que explique la justificación de negocio. Por defecto, los errores siempre deben manejarse explícitamente, no descartarse en silencio.
.avif)
