Foros del Web » Programando para Internet » PHP »

Capturar excepcion no funciona

Estas en el tema de Capturar excepcion no funciona en el foro de PHP en Foros del Web. Buenas, Estoy intentando captura esta excepción de si no encuentra la pagina web, pero no lo consigo, no sé que estoy haciendo mal. @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); ...
  #1 (permalink)  
Antiguo 26/01/2011, 03:22
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 9 meses
Puntos: 20
Capturar excepcion no funciona

Buenas,

Estoy intentando captura esta excepción de si no encuentra la pagina web, pero no lo consigo, no sé que estoy haciendo mal.

Código PHP:
Ver original
  1. function ParserWebSimple($url,$expresion,$debug=false,$notifica=false){
  2.     try {
  3.         $web = file_get_contents($url);
  4.     }catch (Exception $e) {
  5.         echo 'ERROR: ',  $e->getMessage(), "\n";
  6.     }
  7.     preg_match_all($expresion,$web, $matches);
  8.     $resultado=trim(strip_tags($matches[1][0]));
  9.    
  10.     return $resultado;
  11. }
  12.  
  13. // MAIN
  14. $url='http://www.alternate.es/html/product/Placas_base_Socket_1366/Asus/SABERTOOTH_X58/475921/?tn=HARDWARE&l1=Placas+base&l2=Intel&l3=Socket+1366';
  15. $expresion='|<div id="price" style="position:relative;">(.*?)</div>|is';
  16. echo ParserWebSimple($url,$expresion,$debug=false,$notifica=false);

Si lo ejecuto con una URL correcta funciona, muestra el resultado
177,90 €

En cambio si pongo una URL no correcta

Código PHP:
Ver original
  1. $url='http://www.alternate33.es/html/product/Placas_base_Socket_1366/Asus/SABERTOOTH_X58/475921/?tn=HARDWARE&l1=Placas+base&l2=Intel&l3=Socket+1366';

Me muestra el siguiente error por pantalla

Warning: file_get_contents() [function.file-get-contents]: php_network_getaddresses: getaddrinfo failed: Host desconocido. in C:\AppServ\www\Parseando_Webs\componentes_PC\compo nentes_PC.php on line 13

Warning: file_get_contents(http://www.alternate33.es/html/produ...l3=Socket+1366) [function.file-get-contents]: failed to open stream: php_network_getaddresses: getaddrinfo failed: Host desconocido. in C:\AppServ\www\Parseando_Webs\componentes_PC\compo nentes_PC.php on line 13


La linea 13 es precisamente
$web = file_get_contents($url);

El script no está capturando el error, sabéis qué hago mal?

Muchas gracias de antemano!
  #2 (permalink)  
Antiguo 26/01/2011, 06:44
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 15 años, 2 meses
Puntos: 334
Respuesta: Capturar excepcion no funciona

bueno pues pq file_get_contents no crea una exception en caso de fallar

www.php.net/file_get_contents

te recomiendo leer un poco mas sobre excepciones

www.php.net/exception


Código PHP:
function foo()
{
    throw new 
Exception('capturame');
}

try {
    
foo();
} catch (
Exception $e) {
    echo 
$e->getMessage();


saludos.
  #3 (permalink)  
Antiguo 26/01/2011, 09:04
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 9 meses
Puntos: 20
Respuesta: Capturar excepcion no funciona

Sino crea un exepción como puedo saber si se ha ejecutado bien y que no produzca el warning que produce? hay alguna forma?

He probado tu ejemplo y eso sirve para crear excepciones, me falta el paso previo que es como detecto que la función no funciona bien (ejemplo en el caso que la URL que estoy capturando no es correcta por algún motivo)

Muchas gracias de antemano!
  #4 (permalink)  
Antiguo 26/01/2011, 09:18
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 15 años, 2 meses
Puntos: 334
Respuesta: Capturar excepcion no funciona

pues en el manual dice

Cita:
Valores devueltos

Esta función devuelve la información leída o FALSE en caso de error.
Cita:
If you want to check if the function returned error, in case of a HTTP request an, it's not sufficient to test it against false. It may happen the return for that HTTP request was empty. In this case it's better to check if the return value is a bool.

Código PHP:
<?php 
$result
=file_get_contents("http://www.example.com"); 
if (
$result === false

    
// treat error 
} else { 
    
// handle good case 

?>

saludos.
  #5 (permalink)  
Antiguo 26/01/2011, 09:20
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 7 meses
Puntos: 2135
Respuesta: Capturar excepcion no funciona

Si lees el Manual:
Cita:
This function is similar to file(), except that file_get_contents() returns the file in a string, starting at the specified offset up to maxlen bytes. On failure, file_get_contents() will return FALSE.
Es decir si falla regresa false.

Para hacer una versión que soporte excepciones podrías hacer algo así:
Código PHP:
Ver original
  1. function getFileContents($sFile)
  2. {
  3.         $sContents = @file_get_contents($sFile);
  4.         if ($sContents === false) {
  5.                throw new Exception("Unable to read $sFile");
  6.         }
  7.  
  8.         return $sContents;
  9. }

Saludos.
  #6 (permalink)  
Antiguo 26/01/2011, 09:29
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 9 meses
Puntos: 20
Respuesta: Capturar excepcion no funciona

Gracias a ambos, cuando puse la respuesta volví a releer el manual y vi lo que comentabais un poco después. Al final me ha quedado de la siguiente forma

Código PHP:
Ver original
  1. function getFileContents($sFile)
  2. {
  3.     $sContents = @file_get_contents($sFile);
  4.     if ($sContents === false) {
  5.            throw new Exception("Unable to read $sFile");
  6.     }
  7.     return $sContents;
  8. }
  9.  
  10. function ParserWebSimple($url,$expresion,$debug=false,$notificaErrores=false){
  11.  
  12.     $error_msg=''; // string que recopila los errores que va encontrando
  13.    
  14.     try {
  15.         getFileContents($url);
  16.     }
  17.     catch(Exception $e){
  18.         print $e->getMessage();
  19.     }
  20.     preg_match_all($expresion,$web, $matches);
  21.     $resultado=trim(strip_tags($matches[1][0]));
  22.     if (empty($resultado)){
  23.         $error_msg.='La captura está vacia';
  24.     }
  25.     // Si debug está activado imprime los echo dentro del programa
  26.     // Si notificaErrores esta activado te imprime el string $error_msg
  27.    
  28.     return array($resultado,$error_msg);
  29. }
  30.  
  31. // MAIN
  32. $url='http://www.alternate33.es/html/product/Placas_base_Socket_1366/Asus/SABERTOOTH_X58/475921/?tn=HARDWARE&l1=Placas+base&l2=Intel&l3=Socket+1366';
  33. $expresion='|<div id="price" style="position:relative;">(.*?)</div>|is';
  34. list ($resultado,$error_msg)=ParserWebSimple($url,$expresion,$debug=false,$notificaErrores=false);
  35.  
  36. echo "$resultado<br/>";
  37. echo $error_msg;

Qué diferencia hay entre poner el try/catch y luego hacer el
throw new Exception("Unable to read $sFile");

Que simplemente poner...

Código PHP:
Ver original
  1. function getFileContents($sFile)
  2. {
  3.     $sContents = @file_get_contents($sFile);
  4.     if ($sContents === false) {
  5.            echo "Unable to read $sFile";
  6.     }
  7.     return $sContents;
  8. }

Que ventajas tiene...? porque ha efectos visuales no soy capaz de verlo.

Y porqué el IF tiene 3 === en lugar de solo dos? ($sContents === false)

Muchas gracias de antemano por vuestros consejos!
  #7 (permalink)  
Antiguo 26/01/2011, 10:12
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 7 meses
Puntos: 2135
Respuesta: Capturar excepcion no funciona

Si lees lo que te dejo Hidek1, es para comparar el valor, y el tipo de valor del resultado, en el Manual puedes ver más información.

Respecto a tu segunda duda, si lo pones así no tiene ninguna ventaja, pero es para el control de errores, tal como lo tienes ahorita, no sirve de nada que uses o no uses excepciones, la idea de las excepciones es que floten hacía arriba en las llamadas para que puedas mostrar los errores a los usuarios de una mejor forma:
Código PHP:
Ver original
  1. try {
  2.       $web = ParserWebSimple($url, $exp);
  3. } catch (Exception $e) {
  4.       log($e); // Escribe el error en un log para debug
  5.       echo "Lo sentimos se produjo un error al procesar el request. El error es: " . $e->getMessage();
  6. }

Saludos.
  #8 (permalink)  
Antiguo 26/01/2011, 10:51
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 9 meses
Puntos: 20
Respuesta: Capturar excepcion no funciona

Entonces Gatorv

¿El código completo quedaría asi?

Código PHP:
Ver original
  1. function getFileContents($sFile)
  2. {
  3.     $sContents = @file_get_contents($sFile);
  4.     if ($sContents === false) {
  5.            throw new Exception("Unable to read $sFile");
  6.            // En este momento todo el codigo que venga despues no le ejecuta.
  7.     }
  8.     return $sContents;
  9. }
  10.  
  11. function ParserWebSimple($url,$expresion,$debug=false,$notificaErrores=false){
  12.  
  13.     $error_msg=''; // string que recopila los errores que va encontrando
  14.     getFileContents($url);
  15.     preg_match_all($expresion,$web, $matches);
  16.     $resultado=trim(strip_tags($matches[1][0]));
  17.     if (empty($resultado)){
  18.         $error_msg.='La captura está vacia';
  19.     }
  20.     // Si debug está activado imprime los echo dentro del programa
  21.     // Si notificaErrores esta activado te imprime el string $error_msg
  22.    
  23.     return array($resultado,$error_msg);
  24. }
  25.  
  26. // ------------ MAIN ---------------------------------
  27. $url='http://www.alternate33.es/html/product/Placas_base_Socket_1366/Asus/SABERTOOTH_X58/475921/?tn=HARDWARE&l1=Placas+base&l2=Intel&l3=Socket+1366';
  28. $expresion='|<div id="price" style="position:relative;">(.*?)</div>|is';
  29.  
  30. try {
  31.     $web = ParserWebSimple($url,$expresion,$debug=false,$notificaErrores=false);
  32.     echo "$resultado<br/>";
  33.     echo $error_msg;
  34. } catch (Exception $e) {
  35.       log($e); // Escribe el error en un log para debug
  36.       echo "Lo sentimos se produjo un error al procesar el request. <br/>El error es: " . $e->getMessage();
  37. }


Una pregunta más, supuestamente nunca podrán haber/existir dos excepciones juntas/seguidas no? Ya que cuando hay una excepción automaticamente el programa finaliza y salta al apartado del catch, correcto?

Muchas gracias
  #9 (permalink)  
Antiguo 26/01/2011, 11:17
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 7 meses
Puntos: 2135
Respuesta: Capturar excepcion no funciona

Así es, y también dentro de tu función ParserWebSimple podrías lanzar otra excepción en caso de que este vacio, etc.
  #10 (permalink)  
Antiguo 26/01/2011, 12:55
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 9 meses
Puntos: 20
Respuesta: Capturar excepcion no funciona

Cita:
Iniciado por GatorV Ver Mensaje
Así es, y también dentro de tu función ParserWebSimple podrías lanzar otra excepción en caso de que este vacio, etc.
Y las excepciones no se escriben en log de error de PHP, tienes que forzar su escritura si quieres a través de la funcion error_log() como mencionas o crearte tu propio fichero de errores donde quieres que escriba cada excepcion, verdad?

Y una pregunta más

Se puede saber qué excepción fue la que saltó, para actuar de una manera u otra?
Si consigo que escriba en log de errores lo podré ver allí, pero si quiero saberlo en la propia ejecución del script, se les puede dar algún nombre o identificarlas de alguna manera?

Para que en el código principal del programa pueda saber si ha saltado porque no ha sido capaz de leer el fichero o porque la expresion regular ha devuelto vacio.

Código PHP:
Ver original
  1. try {
  2.     $web = ParserWebSimple($url,$expresion,$debug=false,$notificaErrores=false);
  3.     echo "$resultado<br/>";
  4.     echo $error_msg;
  5. } catch (Exception $e) {
  6.      error_log($e); // Escribe el error en un log para debug
  7.       echo "Lo sentimos se produjo un error al procesar el request. <br/>El error es: " . $e->getMessage();
  8. }


Muchas gracias de antemano!

Última edición por neodani; 26/01/2011 a las 13:01
  #11 (permalink)  
Antiguo 26/01/2011, 15:17
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 7 meses
Puntos: 2135
Respuesta: Capturar excepcion no funciona

Claro es lo padre de POO y de las excepciones puedes crear cuantas necesites y usarlas, por ejemplo:
Código PHP:
Ver original
  1. class File_Exception extends Exception {}
  2. class Blank_Content_Exception extends Exception {}
  3.  
  4. try {
  5.         // Codigo que peude lanzar File_Exception o Blank_Content_Exception
  6. } catch (File_Exception $fe) {
  7.        echo "No se encontro ese archivo";
  8. } catch (Blank_Content_Exception $bce) {
  9.        echo "No tenia contenido";
  10. } catch (Exception $e) {
  11.        echo "Cualquier otro error no contemplado";
  12. }

La función log() no existe es solo un ejemplo de como podrías implementar tu el manejo de errores y escribir en un log la excepcion y todo lo que contiene, en la pagina de PHP puedes ver todos los métodos e información que tiene la clase Exception.

Aparte de que puedes hacer cosas como en tu función getFileContents lanzar una exception del tipo File_Exception y en ParserWebSimple solo cachar ese tipo de excepciones, y dejar que las demás suban.

Etiquetas: excepcion
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:51.