¿El error suprime las malas prácticas?

14

En una pregunta SO que hice aquí acerca de algún código del que no estaba seguro, alguien respondió "BTW, horrible código allí: usa mucho el símbolo de supresión de errores (@)".

¿Hay alguna razón por la cual esta es una mala práctica? Con cosas como:

$db=@new mysqli($db_info) or die('Database error');

, me permite mostrar solo un mensaje de error personalizado. Sin la supresión de errores, aún se mostrará el típico mensaje PHP de:

Advertencia : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo falló: No se conoce dicho host. en alguna \ file \ path en la línea 6

así como 'Error de base de datos'.

¿La supresión de errores siempre es mala y, de ser así, qué tiene de malo específicamente lo anterior?

Actualización: el código real que estoy usando es:

or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b><br />Error occurred on line <b>' . __LINE__ . '</b> of <b>' . __FILE__ . '</b>' : ''))

que elimina todos los resultados anteriores y muestra un mensaje de error. Por lo tanto, el hecho de que el mensaje de error no incluya detalles sobre lo que sucedió específicamente (que la gente parece estar sugiriendo como una razón por la cual la supresión de errores es mala) es irrelevante.

Comunidad
fuente
99
¿Usar una venda en los ojos mientras conduce es una mala práctica?
Damien Roche
¿Cómo podría ser una pregunta seria? Supongo que si te gusta escribir código que lleva horas depurar, la supresión de errores sería algo bueno. Piénselo, su aplicación falla, corrompe los datos ... y no desea saber por qué o dónde en el código. ¿Cuándo sería una buena idea? Debes invitar a tus amigos para que realicen una fiesta general sobre ti ... sigue la misma lógica.
Some Free Mason el
1
@SomeFreeMason Si necesito depurar, entonces simplemente establecería $ debug_mode en TRUE, ya que el código real que estoy usando es:or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))
@Paradoxical: Me doy cuenta de que el estado de manejo de excepciones / errores en PHP es un poco FUBAR, pero usted es consciente de que puede desactivar la visualización de errores en su configuración de PHP, ¿verdad?
Phoshi
@Phoshi desafortunadamente el servicio de alojamiento que estoy usando no me da acceso a php.ini

Respuestas:

14

Creo que está haciendo lo correcto al suprimir el error, porque está implementando su propio manejo de errores.

Puede ser más fácil considerar el equivalente en, por ejemplo, Java. Suprimir el error usando @es análogo a tragar una excepción. El siguiente código, que es similar al suyo, es razonable:

try {
    db = new MySQLi(dbInfo);
} catch (SQLException connectionFailure) {
    die("Database error");
}

(Bueno, en Java, no querrás que el motor de servlet muera, pero entiendes la idea).

Sin embargo, esto no es aceptable:

try {
    db = new MySQLi(dbInfo);
} catch (Exception e) {
}

La mayor parte de la supresión de errores PHP se realiza descuidadamente, de forma análoga al último ejemplo, de ahí la reacción instintiva contra su código.

200_success
fuente
3
No llamaría a atrapar la excepción y simplemente detener la ejecución para "manejarla". Si puedes resolver el problema, genial, hazlo. Si no puedes, ¿qué demonios estás haciendo para atraparlo? Para esto tenemos manejadores de excepciones de nivel superior. Capturar excepciones en este caso es solo asegurarse de tener un código de manejo de errores esparcido por toda su base de código.
Phoshi
7

La supresión de errores es mala, porque no solo oculta la información que ya conoce ( algo salió mal). También puede ocultar información vital para la depuración que desconoce ( qué , dónde y por qué ).

En este ejemplo específico, " Error de base de datos " no es un mensaje de error muy bueno. Algo salió mal con el DB. No muy esclarecedor. La “ Advertencia: mysqli :: mysqli (): php_network_getaddresses: getaddrinfo falló: no se conoce dicho host. en alguna \ file \ ruta en la línea 6 "es en realidad un mejor mensaje de error. Le da una ubicación y una razón para el problema. Puede saltar directamente y comenzar a depurar, porque el error ya se ha localizado.

Por supuesto, los diseñadores de bibliotecas a veces tienden a mostrar muchas advertencias irrelevantes. No conozco PHP lo suficientemente bien como para saber si tiene una forma de filtrar las advertencias que no le interesan. Sé que leer a través de un seguimiento de pila de cien líneas no es muy esclarecedor. Pero la respuesta correcta a demasiada información no es reducir la cantidad de información a cero , sino filtrar partes irrelevantes en algún momento. El @operador no tiene esta granularidad (su lema es todo o nada ) y, por lo tanto, no es una herramienta adecuada para la gestión eficaz de errores.

Hay algunos casos en los que sabe que aparecerá un cierto error y que solucionar el problema real es más costoso que silenciar el mensaje (y sufrir las posibles consecuencias de eso). Este podría ser el caso en un guión único, pero meter los dedos en los oídos y decir " la la la " no es una respuesta profesional a los errores (potenciales).

amon
fuente
55
No quiere decirles a sus usuarios el error exacto. Les informa que el error está de su lado y que está trabajando en ello. Puede registrar los errores en su servidor y configurar alertas para que lo sepa automáticamente, pero no hay ninguna razón para mostrar estos errores al usuario.
Jeroen Vannevel
1
Sin embargo, en un sitio en vivo, seguramente sería mejor para un mensaje de error que el usuario típico puede entender que se muestra, en lugar de "algo de basura técnica sobre un mysqli, sea lo que sea". Si estoy tratando de depurarlo, entonces eliminaría la supresión de error, pero en un sitio en vivo, no estoy de acuerdo con que se muestre el error completo.
3
@Paradoxical En un sitio serio, no mostrarías un mensaje de error como "error de base de datos" y nada más. Mostraría una página genérica de "error interno del servidor" con mucha pelusa adicional, estilo, pie de página, etc., que dietampoco es adecuada para ninguno. Y la información detallada debe ir a un registro independientemente de lo que muestre al usuario .
1
¿No hay forma de presentar un mensaje fácil de usar en la pantalla y escribir el mensaje técnico en un archivo de registro?
FrustratedWithFormsDesigner
3
display_errorsapagado, log_errorsencendido, y eres bastante bueno para ir, haz lo que quieras al detectar un error, pero no lo tires.
Escrito el
0

Eliminar errores es malo porque oculta el problema, que muchas veces ni siquiera conocemos y puede dar lugar a un comportamiento inesperado que puede resultar muy costoso en algunas aplicaciones críticas, por ejemplo, en aplicaciones que se utilizan en dominios financieros, de salud y de defensa.

Tampoco es una buena idea tener excepciones no controladas en el código y mostrar los mensajes de error reales al usuario, ya que puede dar lugar a problemas de seguridad porque los mensajes de error generalmente revelan mucho sobre su código, lo que puede ayudar a los usuarios malintencionados y a los piratas informáticos a manipular el sistema.

Por lo tanto, la buena práctica es manejar los errores en diferentes niveles, por ejemplo, en el nivel más alto puede manejar el error simplemente registrando el error real y mostrando un mensaje simple y fácil de usar para el usuario.

Sajad Deyargaroo
fuente
0

Sí, el operador de supresión de errores generalmente es una mala idea.

Debe administrar los informes de errores en la configuración ( php.ini). Por lo tanto, puede elegir una configuración diferente para cada entorno (por ejemplo, dejar advertencias en desarrollo y ocultarlas en producción).

La única situación en la que el uso @podría tener sentido es cuando desarrolla una biblioteca para otros desarrolladores. Si elige voluntariamente hacer algo que produce una advertencia, y no quiere molestar a los usuarios de su biblioteca con una advertencia que no depende de ellos, @podría ser una solución.

No puedo pensar en ningún otro uso.

lortabac
fuente