Skip to content

Commit fa78b6f

Browse files
authored
fix: improve request 4xx error handling (#228)
* fix: improve request 4xx error handling Signed-off-by: Anupam Kumar <kyteinsky@gmail.com> * chore: rename RequestException4xx to FatalRequestException Signed-off-by: Anupam Kumar <kyteinsky@gmail.com> * fix: extend FatalRequestException from RuntimeException Signed-off-by: Anupam Kumar <kyteinsky@gmail.com> --------- Signed-off-by: Anupam Kumar <kyteinsky@gmail.com>
1 parent a5ea191 commit fa78b6f

3 files changed

Lines changed: 42 additions & 9 deletions

File tree

lib/BackgroundJobs/ActionJob.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace OCA\ContextChat\BackgroundJobs;
1111

1212
use OCA\ContextChat\Db\QueueActionMapper;
13+
use OCA\ContextChat\Exceptions\FatalRequestException;
1314
use OCA\ContextChat\Logger;
1415
use OCA\ContextChat\Service\DiagnosticService;
1516
use OCA\ContextChat\Service\LangRopeService;
@@ -125,6 +126,9 @@ protected function run($argument): void {
125126
}
126127
$this->diagnosticService->sendHeartbeat(static::class, $this->getId());
127128
$this->actionMapper->removeFromQueue($entity);
129+
} catch (FatalRequestException $e) {
130+
$this->logger->warning('Error performing action "' . $entity->getType() . '" and removing it from queue: ' . $e->getMessage(), ['exception' => $e]);
131+
$this->actionMapper->removeFromQueue($entity);
128132
} catch (\RuntimeException $e) {
129133
$this->logger->warning('Error performing action "' . $entity->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
130134
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
6+
* SPDX-License-Identifier: AGPL-3.0-or-later
7+
*/
8+
9+
10+
namespace OCA\ContextChat\Exceptions;
11+
12+
/**
13+
* For 4xx responses from the context_chat_backend
14+
*/
15+
class FatalRequestException extends \RuntimeException {
16+
}

lib/Service/LangRopeService.php

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace OCA\ContextChat\Service;
99

1010
use OCA\ContextChat\AppInfo\Application;
11+
use OCA\ContextChat\Exceptions\FatalRequestException;
1112
use OCA\ContextChat\Exceptions\RetryIndexException;
1213
use OCA\ContextChat\Logger;
1314
use OCA\ContextChat\Public\IContentProvider;
@@ -42,6 +43,7 @@ public function __construct(
4243
* @param string|null $contentType
4344
* @return array
4445
* @throws RuntimeException
46+
* @throws FatalRequestException
4547
*/
4648
private function requestToExApp(
4749
string $route,
@@ -128,13 +130,6 @@ private function requestToExApp(
128130
$params,
129131
$options,
130132
);
131-
if (is_array($response) && isset($response['error'])) {
132-
throw new RuntimeException('Error during request to Context Chat Backend (ExApp): ' . $response['error']);
133-
}
134-
if (is_array($response)) {
135-
// this should never happen since app_api only returns errors in an array
136-
throw new RuntimeException('Error during request to Context Chat Backend (ExApp): response is not a valid response object');
137-
}
138133

139134
$resContentType = $response->getHeader('Content-Type');
140135
if (strpos($resContentType, 'application/json') !== false) {
@@ -164,14 +159,22 @@ private function requestToExApp(
164159
}
165160

166161
if ($response->getStatusCode() >= 500) {
167-
// only throw for 5xx errors
168162
throw new RuntimeException(
169163
'Error received from Context Chat Backend (ExApp) with status code '
170164
. $response->getStatusCode()
171165
. ': '
172166
. (isset($finalBody['error']) ? $finalBody['error'] : 'unknown error')
173167
);
174168
}
169+
170+
if ($response->getStatusCode() >= 400) {
171+
throw new FatalRequestException(
172+
'Error received from Context Chat Backend (ExApp) with status code '
173+
. $response->getStatusCode()
174+
. ': '
175+
. (isset($finalBody['error']) ? $finalBody['error'] : json_encode($finalBody))
176+
);
177+
}
175178
}
176179

177180
return $finalBody;
@@ -301,7 +304,17 @@ public function indexSources(array $sources): array {
301304
];
302305
}, $sources);
303306

304-
$response = $this->requestToExApp('/loadSources', 'PUT', $params, 'multipart/form-data');
307+
try {
308+
$response = $this->requestToExApp('/loadSources', 'PUT', $params, 'multipart/form-data');
309+
} catch (FatalRequestException $e) {
310+
// do not retry on 4xx errors
311+
$this->logger->warning('Error while indexing sources: ' . $e->getMessage(), [
312+
'exception' => $e,
313+
'sourceIds' => array_map(fn (Source $source) => $source->reference, $sources),
314+
]);
315+
return ['loaded_sources' => [], 'sources_to_retry' => []];
316+
}
317+
305318
if (
306319
!isset($response['loaded_sources']) || !is_array($response['loaded_sources'])
307320
|| !isset($response['sources_to_retry']) || !is_array($response['sources_to_retry'])

0 commit comments

Comments
 (0)