Handler de errores global
QuietGuard\Monitor\ErrorHandler conecta los handlers globales de PHP para que un host PHP simple, sin pipeline de excepciones de framework, reporte igualmente los errores no capturados. Los frameworks (Laravel, Symfony) tienen sus propios hooks y no deben llamarlo.
Registro
ErrorHandler::register() es una única llamada estática que recibe un Reporter configurado:
Llámelo una vez, lo antes posible en su bootstrap, después de construir el Reporter.
Qué registra
register() cablea tres hooks globales:
set_exception_handler: todoThrowableno capturado se envía mediante$reporter->reportException($e). El handler encadena: si otro handler de excepciones global estaba registrado antes deErrorHandler::register(), sigue ejecutándose después de que la excepción se haya reportado (el monitor reporta primero y luego delega). Cuando no existe ningún handler previo, la excepción (mensaje, fichero:línea y stack trace) se escribe enerror_log, igual que lo que el comportamiento por defecto de PHP habría registrado: instalar la monitorización nunca elimina, por tanto, el registro local del fallo en el host.set_error_handler: un error de PHP lanzado se encapsula en unaErrorExceptiony luego se reporta, siempre que su severidad alcance el umbral descrito más abajo. Comprueba primeroerror_reporting() & $severity, de modo que los valores suprimidos con@o por debajo del nivelerror_reportingactual se ignoran. A continuación devuelvefalsepara que la gestión de errores normal de PHP se ejecute igualmente.register_shutdown_function: en el apagado, se inspeccionaerror_get_last()y, si se trata de un tipo fatal (E_ERROR,E_PARSE,E_CORE_ERROR,E_COMPILE_ERROR), se reporta unaErrorException. Esto captura las fatales que el handler de errores no puede interceptar.
Todos los caminos pasan por el Reporter, que nunca lanza excepciones: registrar estos handlers no puede, por tanto, romper el host.
El umbral de severidad, y el tope que lo acompaña
register() recibe dos argumentos opcionales:
Por defecto solo se reportan E_USER_ERROR y E_RECOVERABLE_ERROR. Antes se transmitía toda severidad, con un POST síncrono cada una, sin umbral, sin deduplicación y sin tope: un solo E_WARNING dentro de un bucle sobre quinientas filas eran quinientas llamadas HTTP bloqueantes en una carga de página, lo que el visitante lee como una caída y consume la cuota mensual de un plan gratuito en un día.
Las verdaderas fatales están ausentes del valor por defecto a propósito. PHP no llama a ningún handler de errores de usuario para E_ERROR, E_PARSE, E_CORE_ERROR ni E_COMPILE_ERROR, y es el hook de apagado anterior el que ya las captura. Lo que el valor por defecto conserva es el par que un host lanza de verdad y con intención: una fatal de aplicación, y un error de tipo que PHP dejó pasar.
Se aplican dos protecciones sea cual sea la máscara:
- un reporte por sitio y por petición: el mismo error lanzado cien veces en el mismo
archivo:líneaes un solo hecho, y los otros noventa y nueve POST son latencia de la aplicación anfitriona, no algo que a usted le toque gastar; - un tope de
$maxPerRequest, 20 por defecto, porque una máscara no ve un bucle: cincuenta líneas distintas pasan cualquier umbral y siguen siendo cincuenta peticiones.
Pase la máscara de forma explícita para ampliarla, sabiendo lo que cuesta:
Un bootstrap PHP mínimo
El SDK de Laravel y el bundle de Symfony no utilizanErrorHandler: cada uno conecta el pipeline de excepciones de su framework. El plugin de WordPress sí lo utiliza, ya que WordPress no tiene un pipeline de excepciones propio, y toma el umbral por defecto. ReserveErrorHandlerpara un host que carezca de su propio pipeline de excepciones.
Está leyendo la documentación PHP Core v1.0.