Errores y excepciones
Cómo falla una aplicación hecha con PiecesPHP, qué ve quien la usa y qué queda anotado. Desde la 9.0.0 hay dos
clases de error, y elegir bien cuál lanzas es la mitad del trabajo.
Graves y suaves
| Graves | Suaves | |
|---|---|---|
| Qué son | Excepciones que nadie captura, E_ERROR, E_PARSE, E_RECOVERABLE_ERROR, E_USER_ERROR |
E_WARNING, E_NOTICE, E_DEPRECATED (y E_USER_DEPRECATED), y lo que anotas con log_soft_error(); también E_USER_WARNING y E_USER_NOTICE, que no rompen ni en local |
| En producción | La petición termina: página o JSON 500 con la referencia | La petición sigue; queda anotado con su referencia |
| En local | Igual, y además ves el detalle | Rompe, como un grave, para que lo arregles (salvo log_soft_error(), que nunca rompe) |
| Se anota | Siempre, una entrada por vez | Una entrada por firma (tipo, archivo, línea) y día, con un contador de repeticiones |
La regla para elegir: si seguir adelante deja algo a medias o mal hecho, lanza una excepción (grave). Si lo que falla no impide terminar bien, anótalo como suave.
Lanzar una excepción
Usa la de PHP que diga lo que pasó (\InvalidArgumentException, \RuntimeException, \DomainException…) o la base
del framework, PiecesPHP\Core\Exceptions\BaseException, cuando quieras adjuntar datos para quien investigue:
use PiecesPHP\Core\Exceptions\BaseException;
$exception = new BaseException('El importador no reconoce la columna «fecha_campo»');
$exception->setExtraData(['archivo' => $nombreArchivo, 'columna' => $columna]);
throw $exception;
Envuelve, no tapes: si capturas una excepción para lanzar otra más clara, pásale la original como previous. El
registro guarda la cadena entera, con la traza de cada una:
try {
$cliente->enviar($datos);
} catch (\Throwable $e) {
throw new \RuntimeException('No se pudo enviar la solicitud al proveedor', 0, $e);
}
Para responder 403 o 404 a una petición no lances una excepción genérica: usa las respuestas del enrutador
(NotFoundException de PiecesPHP\Core\Routing\Slim3Compatibility\Exception) o deja que los permisos de la ruta hagan su
trabajo. Un 404 o un 403 no es un error del sistema.
Anotar algo suave
$referencia = log_soft_error('El proveedor de mapas no respondió; se pinta sin teselas', [
'proveedor' => 'mapbox',
'estado' => $codigoHttp,
]);
Devuelve la referencia de la entrada, y '' si no se pudo anotar. No rompe nunca, tampoco en local. Dos llamadas
desde la misma línea el mismo día cuentan como una sola entrada con su contador, y se queda el primer mensaje.
Qué ve quien usa la aplicación
- Fuera de local, una excepción que nadie captura solo enseña un mensaje genérico y su referencia
(
ERR-20261010-A1B2C3); en JSON,{"success": false, "message": "…", "reference": "ERR-…"}. Ni el mensaje, ni el archivo, ni la traza. - En local, todo.
Pídele a quien te reporte un fallo la referencia. Con ella, en Registros › Errores (solo root), la escribes en el
buscador o abres ?tab=errors&ref=ERR-…, y tienes la entrada entera: tipo, mensaje, archivo y línea, la traza, las
excepciones previas, los datos adicionales y el contexto de la petición (método, ruta, dirección y usuario).
Lo que NUNCA va en un mensaje ni en los datos adicionales
Contraseñas, tokens, claves de API, el contenido de un formulario, datos personales de terceros. El registro lo lee root y se copia en los respaldos. El contexto de la petición se guarda sin la cadena de consulta, sin cabeceras y sin cuerpo, precisamente por eso; no lo metas tú a mano.
Dónde queda
src/app/logs/error.log.jsonl: una entrada por línea; solo crece, se escribe con cerrojo y rota por tamaño alogs/olds/.src/app/logs/error-traces/: cada traza distinta, guardada una vez y nombrada por su huella.src/app/logs/error-soft/: los contadores de los suaves, uno por firma y día.- Cuánto duran: la tarea diaria «Purgar registros viejos» borra los contadores de suaves de más de 30 días
(
GenericHandler::SOFT_RETENTION_DAYS) y las trazas de más de 90 (TRACE_RETENTION_DAYS). Una entrada cuya traza ya se purgó se sigue abriendo, sin la traza. bin/cli clean-logsvacía todo lo anterior de una vez.
Root ve además un aviso flotante, «Hay N errores nuevos desde tu última visita», que lleva a Registros › Errores; se oculta desde Avisos del sistema.