From 6071887caf7f4b0979dec407314875b6082cfcde Mon Sep 17 00:00:00 2001 From: Matthieu Napoli Date: Mon, 28 Sep 2026 14:45:33 +0200 Subject: [PATCH] Let Bref Cloud find the error of a failed `serverless deploy` The CLI sent the line after `Error:` in the osls output as the deployment's error message, which is often not the useful one: for a CloudFormation failure, AWS's reason is on the next line. The whole osls output is already pushed as the deployment's logs, so Bref Cloud now finds the error there, and the CLI sends none when osls fails. This also removes the check for a missing `npx`, which never matched (it looked for `npo: command not found`): Bref Cloud adds that hint instead. Claude-Session: https://claude.ai/code/session_01Awk33iZ9mDSg1xgSAPkgGK --- src/Components/ServerlessFramework.php | 30 ++++---------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/src/Components/ServerlessFramework.php b/src/Components/ServerlessFramework.php index 8eb24c4..f30f431 100644 --- a/src/Components/ServerlessFramework.php +++ b/src/Components/ServerlessFramework.php @@ -43,12 +43,11 @@ public function deploy(int $deploymentId, string $environment, array $awsCredent $oslsPackage = ($input->hasOption('osls4') && $input->getOption('osls4')) ? 'osls@4' : 'osls@3'; $newLogs = ''; - $entireSlsOutput = ''; try { $process = $this->serverlessExec($oslsPackage, 'deploy', $environment, $awsCredentials, $options); - async(function () use ($process, &$newLogs, &$entireSlsOutput) { + async(function () use ($process, &$newLogs) { while (($chunk = $process->getStdout()->read()) !== null) { if (empty($chunk)) continue; foreach (self::IGNORED_LOGS as $ignoredLog) { @@ -56,10 +55,9 @@ public function deploy(int $deploymentId, string $environment, array $awsCredent } IO::verbose($chunk); $newLogs .= $chunk; - $entireSlsOutput .= $chunk; } }); - async(function () use ($process, &$newLogs, &$entireSlsOutput) { + async(function () use ($process, &$newLogs) { while (($chunk = $process->getStderr()->read()) !== null) { if (empty($chunk)) continue; foreach (self::IGNORED_LOGS as $ignoredLog) { @@ -67,7 +65,6 @@ public function deploy(int $deploymentId, string $environment, array $awsCredent } IO::verbose($chunk); $newLogs .= $chunk; - $entireSlsOutput .= $chunk; } }); // Send logs to Bref Cloud every x seconds @@ -91,14 +88,8 @@ public function deploy(int $deploymentId, string $environment, array $awsCredent $newLogs .= "Error while running 'serverless deploy', deployment failed\n"; IO::writeln("Error while running 'serverless deploy', deployment failed"); - // If `npx` is not installed throw a clear error message - if (str_contains($entireSlsOutput, 'npo: command not found')) { - $brefCloud->markDeploymentFinished($deploymentId, false, 'NPM is not installed. Please make sure Node and NPM are installed: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm', $newLogs); - return; - } - - $errorMessage = $this->findErrorMessageInServerlessOutput($entireSlsOutput); - $brefCloud->markDeploymentFinished($deploymentId, false, 'Serverless Framework error: ' . $errorMessage, $newLogs); + // Bref Cloud finds the error in the logs + $brefCloud->markDeploymentFinished($deploymentId, false, null, $newLogs); return; } @@ -265,17 +256,4 @@ private function cleanupCfOutputs(mixed $outputs): array return $result; } - - private function findErrorMessageInServerlessOutput(string $entireSlsOutput): string - { - // Try to find the next line after `Error:\n` - $lines = explode("\n", trim($entireSlsOutput)); - foreach ($lines as $i => $line) { - if ($line === 'Error:' && isset($lines[$i + 1])) { - return $lines[$i + 1]; - } - } - // Return the last line or fallback to a generic message - return $line ?: 'The "serverless deploy" command failed with an unknown error.'; - } } \ No newline at end of file