Defensive : timeout shell sur pagedjs-cli + message d'erreur explicite
All checks were successful
Deploy / deploy (push) Successful in 18s

Wrapper `timeout 360` autour de pagedjs-cli pour SIGTERM-er le process si
Chrome hang au-delà du protocolTimeout interne. Détecte le code 124 du shell
timeout pour donner un message clair à l'utilisateur.

Cron de cleanup orphan installé manuellement sur le VPS dans
/etc/cron.d/web2print-cleanup (toutes les 15 min, appelle worker.php --cleanup).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-05-04 10:50:12 +02:00
parent 56f5a45b7d
commit 8c8c0b0b91
2 changed files with 13 additions and 1 deletions

View file

@ -20,6 +20,7 @@ return [
// Jobs asynchrones // Jobs asynchrones
'job_max_age' => 3600, // 1h, age au-delà duquel un job orphelin est supprimé 'job_max_age' => 3600, // 1h, age au-delà duquel un job orphelin est supprimé
'job_max_duration' => 360, // 6 min, kill SIGTERM via `timeout` si pagedjs-cli ne termine pas
// Limites // Limites
'max_html_size' => 5 * 1024 * 1024, // 5 MB 'max_html_size' => 5 * 1024 * 1024, // 5 MB

View file

@ -87,7 +87,12 @@ class PdfGenerator
public function generateFromUrlToFile(string $url, string $pdfFile, array $options = []): void public function generateFromUrlToFile(string $url, string $pdfFile, array $options = []): void
{ {
$cmd = 'TMPDIR=' . escapeshellarg($this->config['tmp_dir']) . ' '; // Wrap avec `timeout NSEC` : kill SIGTERM si pagedjs-cli ne termine pas dans le délai.
// Garde-fou contre les pages qui bloquent Chrome au-delà du protocolTimeout interne.
$maxDuration = $this->config['job_max_duration'] ?? 360;
$cmd = 'timeout ' . (int)$maxDuration . ' ';
$cmd .= 'TMPDIR=' . escapeshellarg($this->config['tmp_dir']) . ' ';
$cmd .= escapeshellcmd($this->config['pagedjs_bin']); $cmd .= escapeshellcmd($this->config['pagedjs_bin']);
$cmd .= ' ' . escapeshellarg($url); $cmd .= ' ' . escapeshellarg($url);
$cmd .= ' -o ' . escapeshellarg($pdfFile); $cmd .= ' -o ' . escapeshellarg($pdfFile);
@ -103,6 +108,12 @@ class PdfGenerator
$returnCode = 0; $returnCode = 0;
exec($cmd . ' 2>&1', $output, $returnCode); exec($cmd . ' 2>&1', $output, $returnCode);
if ($returnCode === 124) {
$msg = 'Génération interrompue après ' . $maxDuration . 's (timeout shell). La page est probablement trop lourde — réduisez les dimensions des images cover/body.';
$this->log('Timeout shell: ' . $msg);
throw new \Exception($msg);
}
if ($returnCode !== 0) { if ($returnCode !== 0) {
$this->log('Paged.js CLI error (job): ' . implode("\n", $output)); $this->log('Paged.js CLI error (job): ' . implode("\n", $output));
throw new \Exception('PDF generation failed: ' . implode("\n", $output)); throw new \Exception('PDF generation failed: ' . implode("\n", $output));