Ver Mensaje Individual
  #4 (permalink)  
Antiguo 15/08/2008, 09:51
Avatar de shakaran
shakaran
 
Fecha de Ingreso: agosto-2005
Ubicación: España - Ciudad Real
Mensajes: 374
Antigüedad: 18 años, 9 meses
Puntos: 7
De acuerdo Respuesta: Capturar excepción Too many connections (mysql)

Muy buenas soluciones! Me encantaron, he probado con los códigos que me disteis y me sirvio para encontrar en el manual de php un comentario de set_error_handler() donde había un ejemplo muy completo para los errores de SQL.

He probado con y sin @ para silenciar el error y no se observaban cambios.

La primera solución no me ha funcionado, porque se muestra el contenido del
or die(mysql_error()); y no se captura la excepción.
Tal vez php no lo interprete como excepción al ser un warning.

La segunda solución, SI me ha funcionado, pero tengo algunas pegas.
Si pones el set_error_handler() como esta, todos otros posibles errores de PHP (como warnings o notice) se manejarian por ahi. Para evitar eso le añado otro parametro con los errores personalizados del usuario a traves de la constante E_USER_ERROR (equivalente a 256).

Con eso el manejador solo se accionara para errores personalizados que accionemos con un trigger y si queremos asegurarnos aun más podemos restaurar al manejador de php tras acabar la consulta.

Por otro lado, lanzo un error con un manejador en vez de llamar a die() y asi me permite dar más juego al mensaje y a otros posibles errores de usuario.

Os doy las gracias a los dos, porque me pusisteís en "pista" para descubrir por donde tenia que atacar este problema.

Creo que para mi esta bien resuelto, pongo el código por si a alguien más le surge la duda de como utilizarlo (los comentarios y nombres están en ingles porque lo utilizo en un proyecto open source y me interesa que el código este bien internacionalizado, aunque el ingles es muy básico y no cuesta de entenderlo mucho, por supuesto, seguro que el código es mejorable):

Código PHP:
<?
require_once('inc/config.php'); #Load variables of connecction (user,pass,server)

function errorHandler($errno,$errstr,$errfile,$errline)
# Handler for user errors as sql or others
    
switch ($errno)
    {
        case 
E_USER_ERROR# 256
            
if($errstr=='SQL'#String for sql errors
            
{
                switch(
SQL_ERRNO)
                {
                    case 
'1045'# User or pass or server wrong
                        
echo "Error establishing a database connection";
                    break;
                    case 
'1040'#Too many connections
                        
echo 'Too many connections. Retry in a few seconds.<br>';
                    break;
                    case 
'1203'# more than 'max_user_connections' active connections
                        
echo 'Too many active connections. Retry in a few seconds.<br>';
                    break;
                    default: 
# Others mysql errors
                        // handling an sql error
                        
echo "<b>SQL Error</b>[".SQL_ERRNO."] ".SQL_ERROR."<br />\n";
                        echo 
"Query:".SQL_QUERY."<br />\n";
                        echo 
"On line ".SQL_ERROR_LINE." in file ".SQL_ERROR_FILE." ";
                        echo 
", PHP ".PHP_VERSION." (".PHP_OS.")<br />\n";
                        echo 
"Aborting...<br />\n";
                    break;
                }
            }
            else 
#Others customize errors
            
{
                echo 
"<b>My ERROR</b> [$errno] $errstr<br />\n";
                echo 
"  Fatal error on line $errline in file $errfile";
                echo 
", PHP " PHP_VERSION " (" PHP_OS ")<br />\n";
                echo 
"Aborting...<br />\n";
            }
            exit(
1);
            break;
        case 
E_USER_WARNING:
            echo 
"Error User Warning<br>\n";
        break;
        case 
E_USER_NOTICE:
            echo 
"Error User Notice<br>\n";
        break;
        default:
            echo 
"Error Unknown [$errno]<br>\n";
        break;
    }
    return 
true# Don't execute PHP internal error handler
}

function 
sqlErrorHandler($query='',$php_file,$line)
# Handler for sql errors
    
define("SQL_QUERY",$query);
    
define("SQL_ERRNO",mysql_errno());
    
define("SQL_ERROR",mysql_error());
    
define("SQL_ERROR_LINE",$line);
    
define("SQL_ERROR_FILE",$php_file);
    
trigger_error("SQL"E_USER_ERROR);
}

set_error_handler("errorHandler",E_USER_ERROR); # Handler only for user errors

for($i=0;$i<102;$i++)
{
   
// trigger an sql error
   
$db[$i] = @mysql_connect($server,$username_mysql,$password_mysql)
   or 
sqlErrorHandler('Try a lot of connections',$_SERVER['PHP_SELF'],__LINE__);
}
sleep(1000);

restore_error_handler();
echo 
"Done";
?>
__________________
Quijost Backend Engineer - www.quijost.com - Hosting rápido, eficiente y profesional
Blog: www.shakaran.net