From cd91e119ce17b022b3b3716081dc4a86d9c2e488 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 9 Mar 2026 15:40:45 +0530 Subject: [PATCH 1/2] feat: enhance exception handling with standardized error codes Added new constants for common HTTP error codes in the Exception class. Updated various parts of the codebase to utilize these constants for improved error handling, including specific validation and internal error messages in the Appwrite, JSON, and CSV source and destination classes. --- src/Migration/Destinations/Appwrite.php | 2 +- src/Migration/Destinations/JSON.php | 1 + src/Migration/Exception.php | 10 +++++++++- src/Migration/Sources/Appwrite.php | 2 +- src/Migration/Sources/CSV.php | 12 ++++++++---- src/Migration/Sources/JSON.php | 12 ++++++++---- src/Migration/Target.php | 6 +++--- 7 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/Migration/Destinations/Appwrite.php b/src/Migration/Destinations/Appwrite.php index 98a4e94f..82025f5e 100644 --- a/src/Migration/Destinations/Appwrite.php +++ b/src/Migration/Destinations/Appwrite.php @@ -224,7 +224,7 @@ public function report(array $resources = [], array $resourceIds = []): array } catch (AppwriteException $e) { if ($e->getCode() === 403) { - throw new \Exception('Missing scope: ' . $scope, previous: $e); + throw new \Exception('Missing scope: ' . $scope, $e->getCode(), $e); } throw $e; } diff --git a/src/Migration/Destinations/JSON.php b/src/Migration/Destinations/JSON.php index 91660474..91016ef5 100644 --- a/src/Migration/Destinations/JSON.php +++ b/src/Migration/Destinations/JSON.php @@ -139,6 +139,7 @@ protected function import(array $resources, callable $callback): void resourceGroup: $resource->getGroup(), resourceId: $resource->getId(), message: $e->getMessage(), + code: MigrationException::CODE_VALIDATION, previous: $e, )); continue; diff --git a/src/Migration/Exception.php b/src/Migration/Exception.php index 86eb2e22..ff599a09 100644 --- a/src/Migration/Exception.php +++ b/src/Migration/Exception.php @@ -4,6 +4,14 @@ class Exception extends \Exception implements \JsonSerializable { + public const CODE_VALIDATION = 400; + public const CODE_UNAUTHORIZED = 401; + public const CODE_FORBIDDEN = 403; + public const CODE_NOT_FOUND = 404; + public const CODE_CONFLICT = 409; + public const CODE_RATE_LIMITED = 429; + public const CODE_INTERNAL = 500; + public string $resourceName; public string $resourceGroup; @@ -26,7 +34,7 @@ public function __construct( if (\is_numeric($code)) { $code = (int) $code; } else { - $code = 500; // PDOException + $code = self::CODE_INTERNAL; // PDOException } } diff --git a/src/Migration/Sources/Appwrite.php b/src/Migration/Sources/Appwrite.php index 2844bcf1..70ef219e 100644 --- a/src/Migration/Sources/Appwrite.php +++ b/src/Migration/Sources/Appwrite.php @@ -209,7 +209,7 @@ public function report(array $resources = [], array $resourceIds = []): array if ($e->getCode() === 403) { throw new \Exception("Missing required scopes."); } else { - throw new \Exception($e->getMessage(), previous: $e); + throw new \Exception($e->getMessage(), $e->getCode(), $e); } } diff --git a/src/Migration/Sources/CSV.php b/src/Migration/Sources/CSV.php index 3cd227c5..821db4bf 100644 --- a/src/Migration/Sources/CSV.php +++ b/src/Migration/Sources/CSV.php @@ -208,7 +208,7 @@ private function exportRows(int $batchSize): void while (($row = \fgetcsv($stream, 0, $delimiter, '"', '"')) !== false) { if (\count($row) !== \count($headers)) { - throw new \Exception('CSV row does not match the number of header columns.'); + throw new \Exception('CSV row does not match the number of header columns.', Exception::CODE_VALIDATION); } $data = \array_combine($headers, $row); @@ -257,7 +257,7 @@ private function exportRows(int $batchSize): void } if (!\is_array($arrayValues)) { - throw new \Exception("Invalid array format for column '$key': $parsedValue"); + throw new \Exception("Invalid array format for column '$key': $parsedValue", Exception::CODE_VALIDATION); } $parsedData[$key] = array_map(function ($item) use ($type) { @@ -436,7 +436,7 @@ private function validateCSVHeaders(array $headers, array $columnTypes, array $r $messages[] = "$label: '" . \implode("', '", $missingRequired) . "'"; } if (!empty($missingRequired)) { - throw new \Exception('CSV header validation failed: ' . \implode('. ', $messages)); + throw new \Exception('CSV header validation failed: ' . \implode('. ', $messages), Exception::CODE_VALIDATION); } // If there are unknown columns but no missing required columns, just log a warning @@ -479,7 +479,11 @@ private function downloadToLocal( } if (!$success) { - throw new \Exception('Failed to transfer CSV file from device to local storage.', previous: $e ?? null); + throw new \Exception( + 'Failed to transfer CSV file from device to local storage.', + Exception::CODE_INTERNAL, + $e ?? null + ); } $this->downloaded = true; diff --git a/src/Migration/Sources/JSON.php b/src/Migration/Sources/JSON.php index 8abf63d7..4fd0c8eb 100644 --- a/src/Migration/Sources/JSON.php +++ b/src/Migration/Sources/JSON.php @@ -129,7 +129,7 @@ private function exportRows(int $batchSize): void foreach ($items as $index => $item) { if (!\is_array($item)) { - throw new \Exception("JSON item at index $index is not an object."); + throw new \Exception("JSON item at index $index is not an object.", Exception::CODE_VALIDATION); } $rowId = $item['$id'] ?? 'unique()'; @@ -257,7 +257,11 @@ private function downloadToLocal( } if (!$success) { - throw new \Exception('Failed to transfer JSON file from device to local storage.', previous: $e ?? null); + throw new \Exception( + 'Failed to transfer JSON file from device to local storage.', + Exception::CODE_INTERNAL, + $e ?? null + ); } $this->downloaded = true; @@ -270,12 +274,12 @@ private function downloadToLocal( private function validatePermissions(mixed $permissions): array { if (!\is_array($permissions)) { - throw new \Exception('Invalid permissions format; expected an array of strings.'); + throw new \Exception('Invalid permissions format; expected an array of strings.', Exception::CODE_VALIDATION); } foreach ($permissions as $value) { if (!\is_string($value)) { - throw new \Exception('Invalid permission value; expected string.'); + throw new \Exception('Invalid permission value; expected string.', Exception::CODE_VALIDATION); } } diff --git a/src/Migration/Target.php b/src/Migration/Target.php index 8fab14c5..8dbc5a87 100644 --- a/src/Migration/Target.php +++ b/src/Migration/Target.php @@ -147,16 +147,16 @@ protected function call( } if (\curl_errno($ch)) { - throw new \Exception(\curl_error($ch)); + throw new \Exception(\curl_error($ch), Exception::CODE_INTERNAL); } \curl_close($ch); if ($responseStatus >= 400) { if (\is_array($responseBody)) { - throw new \Exception(\json_encode($responseBody)); + throw new \Exception(\json_encode($responseBody), $responseStatus); } else { - throw new \Exception($responseStatus.': '.$responseBody); + throw new \Exception($responseStatus.': '.$responseBody, $responseStatus); } } From 864a351b20ef2a5711ca5aa18a6dcacacd160f06 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 9 Mar 2026 15:53:48 +0530 Subject: [PATCH 2/2] added error code --- src/Migration/Sources/Appwrite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Migration/Sources/Appwrite.php b/src/Migration/Sources/Appwrite.php index 70ef219e..56bb07d5 100644 --- a/src/Migration/Sources/Appwrite.php +++ b/src/Migration/Sources/Appwrite.php @@ -207,7 +207,7 @@ public function report(array $resources = [], array $resourceIds = []): array )['version']; } catch (\Throwable $e) { if ($e->getCode() === 403) { - throw new \Exception("Missing required scopes."); + throw new \Exception('Missing required scopes.', $e->getCode(), $e); } else { throw new \Exception($e->getMessage(), $e->getCode(), $e); }