2012-02-29 21 views
5

Me he metido en un hoyo con el proyecto en el que estoy trabajando. Tengo este proyecto masivo (cientos de miles de líneas) y hay errores de MySQL en todas partes. Estoy en el proceso de limpiarlos ahora.¿Lanzar una excepción sin detener la ejecución?

Tengo esta clase de base de datos por la que pasan todas las consultas, así que lo que he hecho es que siempre que hay un error de SQL, arrojo una excepción ahora. El problema es que no puedo detener la ejecución. Tiene que continuar como siempre, y solo registrar la excepción para poder rastrearlos y solucionarlos de a uno por vez.

Esperaba que set_exception_handler hiciera lo que quisiera, pero los documentos dicen específicamente que detendrá la ejecución después de llamar a mi controlador. Entonces, ¿cómo puedo solucionar esto?

La excepción puede detener la función actual, pero luego quiero que abandone la función, tal vez devuelva nulo o falso, y luego continúe como siempre, pero necesito que llame a mi manejador global de excepciones.


Para aclarar:

Quiero lanzar una excepción de mi clase de base de datos (cada vez que hay un error de SQL). Luego quiero registrar este error y/o mostrar un mensaje en la pantalla hasta que pueda corregir el error de SQL o ajustar la línea ofensiva en un try/catch. No quiero que detenga la ejecución. Si simplemente llamo a alguna función error_handler() en lugar de lanzar una excepción, entonces no puedo atraparla. Si lo encuentro de inmediato (también dentro de la clase DB), no puedo atraparlo más abajo en la pila (a menos que lo vuelva a lanzar, pero luego volvemos a detener la ejecución).

+0

Si ya ha actualizó el código para traducir los errores de MySQL en excepciones, ¿por qué no solo registra el error en lugar de lanzar una excepción? – pgraham

+0

@pgraham: Maldición ... esa es una buena pregunta. La razón es porque quería poder detectar la excepción si no quería que cayera en el controlador de excepción global. Además, quiero una función centralizada de manejo y registro de excepciones. Por último, una vez que limpie los errores, quiero modificar ligeramente el controlador global de excepciones para que realmente * se * muera y arroje un error fatal. – mpen

+1

@downvoter: ¿Le interesa explicar por qué esta es una mala pregunta? – mpen

Respuesta

0

Creo que encontré una solución. En lugar de tirar una excepción, puedo llamar a mi manejador directamente con la excepción:

global_exception_handler(new MySqlException($error_message)); 

De esa manera mi manejador todavía se llama, pero la ejecución continúa.

Y entonces ese mismo manejador de excepciones todavía se puede utilizar para capturar todas las otras excepciones que en realidad son lanzados:

function _global_exception_handler($e) { 
    // log error here 
} 

set_exception_handler('global_exception_handler'); 
+0

No es una * solución alternativa *. – Alexander

+0

que es como agregar una impresión de depuración, ¿no? – alfasin

1

Si le he entendido bien:

function myFunction($params) { 

    try { 

     //your code which throws Exception 

    } catch (Exception $e) { 

     myErrorFunction($e); 
     return false; 
    } 

} 
+0

No, no creo que entiendas todos mis requisitos. ¿Dónde pondría el try/catch? No tengo tiempo ahora para ponerlo en cada consulta SQL, así que tendría que ponerlo exactamente donde lo arrojo ... pero luego no puedo verlo más abajo porque ya lo atrapé . No creo que lo que quiero hacer sea posible. – mpen

+0

Puede ajustar el código completo o simplemente usarlo en su clase de base de datos. ¿Cuántos métodos tienes? 10? 20? Simplemente envuélvalos con esa captura de prueba y cada vez que lo ejecute, por ejemplo '$ db-> myCustonQuery()', usted sabe que si ocurre un error arrojará una excepción que puede manejar en otro lugar. El verdadero objetivo de esta respuesta es que si 'devuelve falso' podrá continuar su ejecución. – Shoe

+0

Si envuelvo todo el código, cuando se lanza una excepción, la ejecución se reducirá a ese punto (la captura); Necesito que continúe más o menos donde quedó (en el lanzamiento). ¿Cuántos métodos? ¿Qué, en mi clase DB? 10-20 es una estimación razonable, pero envolverlos tampoco me permite atraparlo donde quiero. Básicamente quiero * poder * capturar en donde llamo '$ db-> GetSingleRecord()', pero opcionalmente, porque hay miles de llamadas a dicha función y tengo que revisarlas todas. ¿Tiene sentido? Creo que lo que estoy preguntando es poco realista, pero ese sería el caso óptimo. – mpen

Cuestiones relacionadas