Skip to content
This repository was archived by the owner on Apr 27, 2026. It is now read-only.

Commit 2cdfae8

Browse files
pjcdawkinsclaude
andcommitted
fix(api:curl): buffer stdout to prevent 401 error body in output
When a 401 triggers token refresh and retry, the error response body from the initial request was being written to stdout before the retry. With --fail-with-body, curl outputs error bodies to stdout while the status code appears in stderr via --verbose. Buffer stdout when retryOn401 is enabled. Only write the buffer after the request completes successfully. If 401 is detected, discard the buffer before retrying. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 26550d3 commit 2cdfae8

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

src/Service/CurlCli.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,25 @@ public function run($baseUrl, InputInterface $input, OutputInterface $output) {
7676
$process = new Process($commandline);
7777
$shouldRetry = false;
7878
$newToken = '';
79-
$onOutput = function ($type, $buffer) use ($censor, $output, $stdErr, $process, $retryOn401, &$newToken, &$shouldRetry) {
79+
$stdoutBuffer = '';
80+
$onOutput = function ($type, $buffer) use ($censor, $output, $stdErr, $process, $retryOn401, &$newToken, &$shouldRetry, &$stdoutBuffer) {
8081
if ($shouldRetry) {
8182
// Ensure there is no output after a retry is triggered.
8283
return;
8384
}
8485
if ($type === Process::OUT) {
85-
$output->write($buffer);
86+
if ($retryOn401) {
87+
// Buffer stdout so it can be discarded if a 401 triggers a retry.
88+
$stdoutBuffer .= $buffer;
89+
} else {
90+
$output->write($buffer);
91+
}
8692
return;
8793
}
8894
if ($type === Process::ERR) {
8995
if ($retryOn401 && $this->parseCurlStatusCode($buffer) === 401 && $this->api->isLoggedIn()) {
9096
$shouldRetry = true;
97+
$stdoutBuffer = '';
9198
$process->clearErrorOutput();
9299
$process->clearOutput();
93100

@@ -107,6 +114,11 @@ public function run($baseUrl, InputInterface $input, OutputInterface $output) {
107114

108115
$process->run($onOutput);
109116

117+
if (!$shouldRetry && $stdoutBuffer !== '') {
118+
$output->write($stdoutBuffer);
119+
$stdoutBuffer = '';
120+
}
121+
110122
if ($shouldRetry) {
111123
// Create a new curl process, replacing the access token.
112124
$commandline = $this->buildCurlCommand($url, $newToken, $input);
@@ -118,6 +130,10 @@ public function run($baseUrl, InputInterface $input, OutputInterface $output) {
118130

119131
$stdErr->writeln(sprintf('Running command: <info>%s</info>', $censor($commandline)), OutputInterface::VERBOSITY_VERBOSE);
120132
$process->run($onOutput);
133+
134+
if ($stdoutBuffer !== '') {
135+
$output->write($stdoutBuffer);
136+
}
121137
}
122138

123139
return $process->getExitCode();

0 commit comments

Comments
 (0)