php: try-catch no detecta todas las excepciones

4 minutos de lectura

Estoy tratando de hacer lo siguiente:

try {
    // just an example
    $time="wrong datatype";
    $timestamp = date("Y-m-d H:i:s", $time);
} catch (Exception $e) {
    return false;
}
// database activity here

En resumen: inicializo algunas variables para ponerlas en la base de datos. Si la inicialización falla por cualquier motivo, por ejemplo, porque $time no es el formato esperado, quiero que el método devuelva falso y no ingrese datos incorrectos en la base de datos.

Sin embargo, errores como este no son capturados por la instrucción ‘catch’, sino por el controlador de errores global. Y luego el guión continúa.

¿Hay alguna forma de evitar esto? Simplemente pensé que sería más limpio hacerlo así en lugar de verificar manualmente cada variable, lo que parece ineficaz considerando que en el 99% de los casos no sucede nada malo.

  • Eso es porque las excepciones no se implementan universalmente en PHP. Son una adición de PHP5, y muy pocas de las funciones integradas las lanzarán. En su lugar, deberá verificar los valores de retorno de la mayoría de las funciones.

    –Michael Berkowski

    17 de marzo de 2013 a las 14:07


try {
  // call a success/error/progress handler
} catch (\Throwable $e) { // For PHP 7
  // handle $e
} catch (\Exception $e) { // For PHP 5
  // handle $e
}

  • Gracias por este fragmento de código, que podría proporcionar una ayuda limitada e inmediata. A explicación apropiada mejoraría en gran medida su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que ha hecho.

    – rsjaffe

    6 ago. 2018 a las 4:00

  • @YvetteColomb, ¡Oh, aquí hay un fantasma que me quita la opinión! 😉 Pero sigo creyendo que algunas preguntas puede tener una respuesta de una sola palabra. Cual es la respuesta a la pregunta 4 + 4? Se puede agregar una respuesta muy corta sin explicación, solo una palabra: 2, entonces, ¿por qué tenemos que escribir: “La respuesta correcta a la declaración 4 + 4 que fue su pregunta fue 2 …!” Nuevamente, también estoy de acuerdo con las explicaciones más detalladas en las respuestas. Pero quiero decir, sólo algunos de ellos.

    – Nabi Kaz

    12 de agosto de 2018 a las 13:24

  • Esta breve respuesta es todo lo que necesitaba. Pero no estoy seguro de que 4 + 4 = 2.

    – Musik Animal

    16 de enero de 2019 a las 3:16

  • Sí, esto está muy poco documentado, apenas puedes notarlo, si tienes suerte y vienes a ambos. php.net/manual/en/class.error.php y php.net/manual/en/class.exception.php enlaces… porque el que debe contener esto: php.net/manual/en/idioma.excepciones.phpni siquiera contiene la palabra Throwable (en la parte del documento).

    – jave.web

    18 de septiembre de 2019 a las 13:21

  • ¿En qué circunstancias iría esto al último bloque catch? Cuando la clase Exception implementa la interfaz Throwable, ¿no se capturaría esto siempre en el primer bloque catch?

    – Gemmu

    21 de julio de 2021 a las 9:51


Solución #1

Usar Excepción de error para convertir errores en excepciones para manejar:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");

Solución #2

try {
    // just an example
    $time="wrong datatype";
    if (false === $timestamp = date("Y-m-d H:i:s", $time)) {
        throw new Exception('date error');
    }
} catch (Exception $e) {
    return false;
}

  • Un par de notas: 1) Si no se desea generar universalmente excepciones en lugar de errores en toda la aplicación, esto se puede habilitar donde se desee y se puede restaurar el manejo regular de errores con restore_error_handler(). 2) Espero que el n. ° 2 aún arroje una advertencia. Se aplica el mismo concepto: el nivel de notificación de errores se puede cambiar con error_reporting() y cambió de nuevo después.

    – Chico listo

    17 de marzo de 2013 a las 14:23

  • La advertencia DEBE SER lanzada de todos modos. Son información que debes guardar en algún lugar. Si no quieres verlo, simplemente apaga error_display

    – Federkun

    17 de marzo de 2013 a las 14:27

  • La solución n. ° 2 es cómo lo hace Js … es bueno si sabes lo que estás haciendo

    – Ray Foss

    3 de febrero de 2018 a las 19:51

  • Pregunta de seguimiento: ¿Es una buena idea usar la solución n. ° 1 en sus aplicaciones MVC? Siento que usarlo globalmente anula el propósito de las Excepciones mientras lo uso repetidamente restore_error_handler() se siente muy hacker.

    usuario2286243

    19 de marzo de 2018 a las 12:50


  • Solo en modo de depuración @VarunAgrawal, durante el desarrollo. No confiaría en una configuración global de php para manejar correctamente cómo se ejecutará su aplicación al final.

    – Federkun

    20/03/2018 a las 20:50

Los más cortos que he encontrado:

set_error_handler(function($errno, $errstr, $errfile, $errline ){
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});

Hace que todos los errores se conviertan en instancias de atrapables ErrorException

avatar de usuario
Amal Magdy

Es posible usar catch(Throwable $e) para capturar todas las excepciones y errores como este:

catch ( Throwable $e){
    $msg = $e->getMessage();
}

También es posible definir múltiples tipos para el $e parámetro en catch:

try {
    // just an example
    $time="wrong datatype";
    $timestamp = date("Y-m-d H:i:s", $time);
} catch (Exception|TypeError $e) {
    return false;
}

  • Esto es MUCHO mejor que la respuesta aceptada.

    – Nexario

    19 de mayo a las 22:02

  • Esto es MUCHO mejor que la respuesta aceptada.

    – Nexario

    19 de mayo a las 22:02

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad