Skip to content

Commit ef5a93f

Browse files
committed
chore: abstract formatErrorMessage
1 parent 11bb934 commit ef5a93f

7 files changed

Lines changed: 151 additions & 22 deletions

File tree

src/Agents/Adapter.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ abstract public function setModel(string $model): self;
9393
*/
9494
abstract public function isSchemaSupported(): bool;
9595

96+
/**
97+
* Format error message
98+
*
99+
* @param mixed $json
100+
* @return string
101+
*/
102+
abstract protected function formatErrorMessage($json): string;
103+
96104
/**
97105
* Get the current agent
98106
*

src/Agents/Adapters/Anthropic.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ public function getName(): string
446446
* @param mixed $json
447447
* @return string
448448
*/
449-
private function formatErrorMessage($json): string
449+
protected function formatErrorMessage($json): string
450450
{
451451
if (! is_array($json)) {
452452
return '(unknown_error) Unknown error';

src/Agents/Adapters/Deepseek.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,7 @@ protected function process(Chunk $chunk, ?callable $listener): string
183183

184184
$json = json_decode($data, true);
185185
if (is_array($json) && isset($json['error'])) {
186-
$type = $json['error']['type'] ?? '';
187-
$message = $json['error']['message'] ?? 'Unknown error';
188-
189-
return '('.$type.') '.$message;
186+
return $this->formatErrorMessage($json);
190187
}
191188

192189
foreach ($lines as $line) {
@@ -302,4 +299,22 @@ public function getName(): string
302299
{
303300
return 'deepseek';
304301
}
302+
303+
/**
304+
* Extract and format error information from API response
305+
*
306+
* @param mixed $json
307+
* @return string
308+
*/
309+
protected function formatErrorMessage($json): string
310+
{
311+
if (! is_array($json)) {
312+
return '(unknown_error) Unknown error';
313+
}
314+
315+
$errorType = isset($json['error']['type']) ? (string) $json['error']['type'] : 'unknown_error';
316+
$errorMessage = isset($json['error']['message']) ? (string) $json['error']['message'] : 'Unknown error';
317+
318+
return '('.$errorType.') '.$errorMessage;
319+
}
305320
}

src/Agents/Adapters/Gemini.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,7 @@ protected function process(Chunk $chunk, ?callable $listener): string
197197

198198
$json = json_decode($data, true);
199199
if (is_array($json) && isset($json['error'])) {
200-
$error = '('.($json['error']['status'] ?? '').') '.($json['error']['message'] ?? 'Unknown error');
201-
if (! empty($json['error']['details'])) {
202-
$error .= PHP_EOL.json_encode($json['error']['details'], JSON_PRETTY_PRINT);
203-
}
204-
205-
return $error;
200+
return $this->formatErrorMessage($json);
206201
}
207202

208203
foreach ($lines as $line) {
@@ -334,4 +329,23 @@ public function getName(): string
334329
{
335330
return 'gemini';
336331
}
332+
333+
/**
334+
* Extract and format error information from API response
335+
*
336+
* @param mixed $json
337+
* @return string
338+
*/
339+
protected function formatErrorMessage($json): string
340+
{
341+
if (! is_array($json)) {
342+
return '(unknown_error) Unknown error';
343+
}
344+
345+
$errorType = isset($json['error']['status']) ? (string) $json['error']['status'] : 'unknown_error';
346+
$errorMessage = isset($json['error']['message']) ? (string) $json['error']['message'] : 'Unknown error';
347+
$errorDetails = isset($json['error']['details']) ? json_encode($json['error']['details'], JSON_PRETTY_PRINT) : '';
348+
349+
return '('.$errorType.') '.$errorMessage.PHP_EOL.$errorDetails;
350+
}
337351
}

src/Agents/Adapters/OpenAI.php

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,16 @@ function ($chunk) use (&$content, $listener) {
225225
$payload,
226226
);
227227
$body = $response->getBody();
228+
229+
if ($response->getStatusCode() >= 400) {
230+
$json = is_string($body) ? json_decode($body, true) : null;
231+
$content = $this->formatErrorMessage($json);
232+
throw new \Exception(
233+
ucfirst($this->getName()).' API error: '.$content,
234+
$response->getStatusCode()
235+
);
236+
}
237+
228238
$json = is_string($body) ? json_decode($body, true) : null;
229239
if (is_array($json) && isset($json['choices'][0]['message']['content'])) {
230240
$content = $json['choices'][0]['message']['content'];
@@ -253,11 +263,7 @@ protected function process(Chunk $chunk, ?callable $listener): string
253263

254264
$json = json_decode($data, true);
255265
if (is_array($json) && isset($json['error'])) {
256-
if (isset($json['error']['code'], $json['error']['message'])) {
257-
return '('.$json['error']['code'].') '.$json['error']['message'];
258-
}
259-
260-
return is_array($json['error']) ? json_encode($json['error']) : $json['error'];
266+
return $this->formatErrorMessage($json);
261267
}
262268

263269
foreach ($lines as $line) {
@@ -390,4 +396,22 @@ public function getName(): string
390396
{
391397
return 'openai';
392398
}
399+
400+
/**
401+
* Extract and format error information from API response
402+
*
403+
* @param mixed $json
404+
* @return string
405+
*/
406+
protected function formatErrorMessage($json): string
407+
{
408+
if (! is_array($json)) {
409+
return '(unknown_error) Unknown error';
410+
}
411+
412+
$errorType = isset($json['error']['code']) ? (string) $json['error']['code'] : 'unknown_error';
413+
$errorMessage = isset($json['error']['message']) ? (string) $json['error']['message'] : 'Unknown error';
414+
415+
return '('.$errorType.') '.$errorMessage;
416+
}
393417
}

src/Agents/Adapters/Perplexity.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,8 @@ protected function process(Chunk $chunk, ?callable $listener): string
118118
$lines = explode("\n", $data);
119119

120120
$json = json_decode($data, true);
121-
if (is_array($json)) {
122-
if (isset($json['error']['code'], $json['error']['message'])) {
123-
return '('.$json['error']['code'].') '.$json['error']['message'];
124-
}
125-
126-
return $json['error'] ?? 'Unknown error';
121+
if (is_array($json) && isset($json['error'])) {
122+
return $this->formatErrorMessage($json);
127123
}
128124

129125
// Specifically for Authorization and similar errors that return HTML

src/Agents/Adapters/XAI.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Utopia\Agents\Adapters;
44

5+
use Utopia\Fetch\Chunk;
6+
57
class XAI extends OpenAI
68
{
79
/**
@@ -81,4 +83,74 @@ public function getName(): string
8183
{
8284
return 'xai';
8385
}
86+
87+
/**
88+
* Process a stream chunk from the OpenAI API
89+
*
90+
* @param \Utopia\Fetch\Chunk $chunk
91+
* @param callable|null $listener
92+
* @return string
93+
*
94+
* @throws \Exception
95+
*/
96+
protected function process(Chunk $chunk, ?callable $listener): string
97+
{
98+
$block = '';
99+
$data = $chunk->getData();
100+
$lines = explode("\n", $data);
101+
102+
$json = json_decode($data, true);
103+
if (is_array($json) && isset($json['error'])) {
104+
return $this->formatErrorMessage($json);
105+
}
106+
107+
foreach ($lines as $line) {
108+
if (empty(trim($line))) {
109+
continue;
110+
}
111+
112+
if (! str_starts_with($line, 'data: ')) {
113+
continue;
114+
}
115+
116+
// Handle [DONE] message
117+
if (trim($line) === 'data: [DONE]') {
118+
continue;
119+
}
120+
121+
$json = json_decode(substr($line, 6), true);
122+
if (! is_array($json)) {
123+
continue;
124+
}
125+
126+
// Extract content from the choices array
127+
if (isset($json['choices'][0]['delta']['content'])) {
128+
$block = $json['choices'][0]['delta']['content'];
129+
130+
if (! empty($block) && $listener !== null) {
131+
$listener($block);
132+
}
133+
}
134+
}
135+
136+
return $block;
137+
}
138+
139+
/**
140+
* Extract and format error information from API response
141+
*
142+
* @param mixed $json
143+
* @return string
144+
*/
145+
protected function formatErrorMessage($json): string
146+
{
147+
if (! is_array($json)) {
148+
return '(unknown_error) Unknown error';
149+
}
150+
151+
$errorType = isset($json['code']) ? (string) $json['code'] : 'unknown_error';
152+
$errorMessage = isset($json['error']) ? (string) $json['error'] : 'Unknown error';
153+
154+
return '('.$errorType.') '.$errorMessage;
155+
}
84156
}

0 commit comments

Comments
 (0)