réponse try { $CID = bin2hex(random_bytes(6)); } catch (\Throwable $e) { $CID = uniqid(); } if (!headers_sent()) { header('X-PP-CID: ' . $CID); // Exposer les entêtes aux scripts front (même si cross-origin CORS le permet) header('Access-Control-Expose-Headers: X-PP-CID, X-PP-Error, X-PP-Error-Code'); } // Chemin du log (modifiable) $logFile = __DIR__ . '/logs/pp_fetch.log'; @is_dir(dirname($logFile)) || @mkdir(dirname($logFile), 0775, true); $pp_log = function (string $level, string $message, array $ctx = []) use ($logFile, $CID) { $line = date('c') . "\t" . $CID . "\t" . $level . "\t" . $message . "\t" . json_encode($ctx, JSON_UNESCAPED_SLASHES) . PHP_EOL; // 3 = fichier error_log($line, 3, $logFile); }; // Optionnel : fonction globale de log manuel if (!function_exists('pp_debug_log')) { function pp_debug_log(string $label, $data = null) { global $pp_log; if (isset($pp_log) && is_callable($pp_log)) { $pp_log('NOTE', $label, ['data' => $data]); } } } // Handler erreurs PHP (non fatales) set_error_handler(function ($severity, $message, $file, $line) use ($pp_log, $PP_DEBUG) { $pp_log('PHP_ERROR', $message, ['file' => $file, 'line' => $line, 'severity' => $severity]); if ($PP_DEBUG && !headers_sent()) { header('X-PP-Error: ' . $message); header('X-PP-Error-Code: ' . (string)$severity); } return false; // laisser PHP continuer son flux normal }); // Exceptions non catchées set_exception_handler(function ($ex) use ($pp_log, $PP_DEBUG) { $pp_log('EXCEPTION', $ex->getMessage(), [ 'file' => $ex->getFile(), 'line' => $ex->getLine(), 'trace' => $ex->getTraceAsString() ]); if ($PP_DEBUG && !headers_sent()) { header('X-PP-Error: ' . $ex->getMessage()); header('X-PP-Error-Code: EXCEPTION'); } http_response_code(500); // status utile pour le front, le body reste inchangé }); // Fatales (parse, compile, etc.) — typiquement ce qui laisse un body vide et casse le JSON register_shutdown_function(function () use ($pp_log, $PP_DEBUG) { $e = error_get_last(); if ($e && in_array($e['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR], true)) { $pp_log('FATAL', $e['message'], ['file' => $e['file'], 'line' => $e['line'], 'type' => $e['type']]); if ($PP_DEBUG && !headers_sent()) { header('X-PP-Error: ' . $e['message']); header('X-PP-Error-Code: ' . (string)$e['type']); } http_response_code(500); } });