El bloque Try / Catch en PHP no detecta la excepción

97

Estoy tratando de ejecutar este Ejemplo # 1 desde esta página: http://php.net/manual/en/language.exceptions.php

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}
try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
?>

Sin embargo, en lugar de la salida deseada, obtengo:

0.2
Fatal error: Uncaught exception 'Exception' with message 'Division by zero.' 
in xxx:
7 Stack trace: #0 xxx(14): inverse(0) #1 {main} thrown in xxx on line 7

El entorno de desarrollador que estoy usando es UniServer 3.5conPHP 5.2.3

Krassi
fuente
1
¿Puedes mostrarnos tu código? El único error que puede cometer para obtener este error es detectar la excepción incorrecta (o ninguna).
Tammo
2
El código es EXACTAMENTE idéntico (acabo de agregar algunas líneas nuevas) ... de todos modos, copié el código una vez más en un archivo de prueba y aquí está el mismo mensaje de error: 0.2 Error fatal: excepción no detectada 'Excepción' con el mensaje 'División por cero . en W: \ www \ test.php: 4 Seguimiento de pila: # 0 W: \ www \ test.php (11): inverso (0) # 1 {main} lanzado en W: \ www \ test.php en la línea 4 Realmente no tengo idea de lo que está pasando allí ... ¿tal vez una configuración de PHP defectuosa?
Krassi
1
Algunas versiones de extensión anteriores causaron problemas con el manejo de excepciones. 5.2.3 es antiguo y puede haber un error detrás del error. ¿Puedes actualizar PHP? UniServer 3.5 también es bastante antiguo, considerando que la versión de producción actual es 5.5. ¿Es 3.5 un error tipográfico?
Salida
1
Mirando la información de lanzamiento de UniServer ( wiki.uniformserver.com/index.php/… ), 3.5 aparentemente no es un error tipográfico. Actualice a UniServer 5.5 y vuelva a intentar el código de muestra.
Salida
1
outis, gracias por el dato :). Esto es lo que hice en ese entonces: cambié a XAMPP (no me gusta la nueva versión de UniServer). 3.5 no es un error tipográfico, pero el servidor funcionó perfectamente para mí, así que nunca me molesté en actualizarlo.
Krassi

Respuestas:

217

Acabo de tener este problema exacto en el que parecía que incluso había copiado el nombre de la excepción y, sin embargo, no lo capté. Resultó que fue mi estúpido error, pero pensé que debería publicar mi caso aquí en caso de que haya alguien más en la misma situación.

Tenía mi excepción en mi espacio de nombres llamado A y el guión estaba en un espacio de nombres llamado B . El problema era que tenía A \ MyException que es igual (en PHP) \ B \ A \ MyException (¡porque mi script está en el espacio de nombres llamado B !). Todo lo que tuve que hacer para solucionarlo fue agregar una barra invertida (o como se llame) al nombre de la excepción para que se vea así: \ A \ MyException

Pijusn
fuente
7
muchas gracias por publicar esto porque hubiera pasado varios días sin darme cuenta de mi error.
tipu
79
Esto resolvió mi problema, debería ser un simple bloque de captura perezoso en código con espacio de nombres catch (\Exception $e). Sin la barra invertida, Exceptiones específico del espacio de nombres y no se comparará (ni se capturará).
joemaller
3
¡Gracias por publicar esto!
Keepkimi
2
Gracias por publicar esto, acabo de pasar las últimas horas volviéndome loco pensando por qué mi bloque de captura no funcionaba. Facepalm mayor.
Mitch
4
¡Salud! Salvó mi día (y neuronas ...) :)
vegetal
67

Pregunta bastante vieja, todavía ...

También tuve este problema (y así fue como encontré esta publicación) pero un simple experimento me permitió encontrar la solución. Intente cambiar Exceptiona \Exception. ¡Trabajó para mi!

EDITAR:

Como señaló sivann en los comentarios, usar el espacio de nombres debería hacer lo mismo. Así que simplemente ponlo use \Exception as Exception;antes de tu declaración de clase.

Enetión
fuente
¡Brillante! :) Probablemente me tomaría horas averiguarlo, pero no pensé en el espacio de nombres. ¡Gracias!
Alexander Gilmanov
¡Si! también: "use \ Exception as Exception;" en la parte superior hace lo mismo.
sivann
@ sii-anik Intente usar el espacio de nombres tal como escribió sivann.
Enethion
solo use Exception;debería hacerlo
Diego Ponciano
¡Gracias! @Enethion
Noamway
32

Tratar de poner catch(\Exception $e) lugar de catch(Exception $e). Si está utilizando un código que no conoce muy bien o, especialmente, si está utilizando un marco, podría anular la excepción de PHP predeterminada con una propia y, por lo tanto, podría ir a la ruta incorrecta y obtener el resultado no deseado. Si acaba de poner \Exception, entonces está seguro de que está detectando la excepción básica de PHP.

Vladimir Despotovic
fuente
@crassi, ¿probaste mi sugerencia?
Vladimir Despotovic
2
Eso
20

No puede usar los típicos bloques try {} catch {} en PHP como podría hacerlo en otro lenguaje como C # (Csharp).

Si haces esto:

try{
    //division by zero
    $number = 5/0;
}
catch(Exception $ex){
    echo 'Got it!';
}

No verá el mensaje "¡Entendido!" mensaje nunca. ¿Por qué? Es solo porque PHP siempre necesita una excepción para ser "lanzada". Debe configurar su propio controlador de errores y lanzar una excepción con él.

Ver función set_error_handler : http://php.net/manual/es/function.set-error-handler.php

Rowinson Gallego
fuente
6
Eso no es lo mismo;) Necesitabas lanzar una excepción tú mismo, y eso fue lo que dije (<< Es solo porque PHP siempre necesita una excepción para ser "lanzada" >>) @JaredFarrish
Rowinson Gallego
Sí, pero ¿cómo no es lo mismo?
Jared Farrish
Ese enlace está muerto, pero encontré esto útil: w3schools.com/php/func_error_set_error_handler.asp
Loathing
En PHP Versión 7.3.9, $number = 5/0;no genera una excepción. $numberestá configurado para ser INF.
virtualmic
6

Sin embargo, mi inicial es que tiene un error tipográfico en el nombre de la excepción que está capturando / lanzando, pero si su código es exactamente el mismo, no estoy seguro de qué está pasando exactamente.

Pruebe la siguiente modificación del script original y pegue los resultados. Ayudará a diagnosticar su problema un poco mejor.

<?php

//set up exception handler to report what we didn't catch
function exception_handler($exception) {

    if($exception instanceof MyException) {
        echo "you didn't catch a myexception instance\n";

    } else if($exception instanceof Exception) {
        echo "you didn't catch a exception instance\n";

    } else {
        echo "uncaught exception of type: ".gettype($exception)."\n";
    }

    echo "Uncaught exception: " , $exception->getMessage(), "\n";
}

//install the handler
set_exception_handler('exception_handler');

class MyException extends Exception {
}

function inverse($x) {
    if (!$x) {
        throw new MyException('Division by zero.');
    }
    else return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (MyException $e) {
    echo 'Caught myexception: ',  $e->getMessage(), "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
?>
francés
fuente
4

Tuve el mismo problema con las siguientes configuraciones,

PHP 5.2.14 (cli) (construido: 12 de agosto de 2010 17:32:30) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies con eAccelerator v0.9.5. 1 , Copyright (c) 2004-2006 eAccelerator, por eAccelerator

La solución es desactivar eAccelerator o actualizarlo. Probé ambos y ambos arreglos funcionaron. El error se informa aquí https://eaccelerator.net/ticket/242 (NB. Firefox se queja de su certificado SSL).

Ahora estoy ejecutando try catch correctamente con las siguientes configuraciones,

PHP 5.2.4 (cli) (construido: 16 de octubre de 2007 09:13:35) Copyright (c) 1997-2007 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies con eAccelerator v0.9.6. 1 , Copyright (c) 2004-2010 eAccelerator, por eAccelerator

Yawar
fuente
3

en Xdebug hay una configuración:

xdebug.show_exception_trace = 1

Esto forzará a php a generar excepciones incluso en un bloque try catch. Convierte esto en0

usuario2950254
fuente
2
En mi caso, tuve que deshabilitar el módulo xdebug por completo (cambiar xdebug.show_exception_trace no fue suficiente).
Thomas Sahlin
Gracias por este recordatorio. Estuve completamente confundido por un tiempo.
Brian Litzinger
3

Si está utilizando PHP 7, es posible que necesite Throwable en lugar de Exception

usuario5528384
fuente
Esta es una publicación bastante antigua. Eche un vistazo a la fecha del tema antes de decidirse a responder. Además, su respuesta no es realmente útil, ya que es: - no completa - no hay explicación por qué
monofone
1
La explicación es que PHP7 usa Throwable en lugar de Exception. Esta discusión fue la primera que encontré cuando encontré el problema y quise contribuir. Comentarios como estos son motivos por los que Stack no es compatible con la comunidad.
user5528384
1
no era mi intención ofenderte. Esta publicación apareció en la cola de revisión "Primeras publicaciones" y, en mi opinión, no fue útil publicar una respuesta a una pregunta bastante antigua. Y en el momento de escribir este artículo, Question Throwable ni siquiera se inventó en el mundo PHP. Sería útil si escribe en su respuesta que Throwable es la interfaz implementada por Exception (y Error) y, por lo tanto, también puede detectarse. Pero no es un complemento de una excepción.
monofone
1

TLDR; asegúrese de tener use Exception;en la parte superior de ambos archivos php

Señor Heelis
fuente
0

Yo también estoy experimentando esto. Leí un comentario de Rowinson Gallego en el que se debe lanzar una excepción. Entonces modifiqué mi código de:

try
{
  $number = 5/0; //or other exception
}
catch(Exception $e)
{
  throw $e;
}

dentro :

try
{
  $number = 5/0; //or other exception
}
catch(Exception $e)
{
  throw new Exception($e->getMessage(),$e->getCode());
}

Funciona.

Fauzie Adriansyah
fuente