Skip to content

Commit 8c8d472

Browse files
committed
Improve backup policy migration validation and error handling
1 parent b0d2b9c commit 8c8d472

2 files changed

Lines changed: 29 additions & 18 deletions

File tree

src/Migration/Destinations/Appwrite.php

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ public function report(array $resources = [], array $resourceIds = []): array
210210
throw $e;
211211
}
212212

213-
// Backups (uses call() instead of SDK, so needs separate error handling)
213+
// Backups use call() instead of the SDK, so they need separate error handling.
214214
if (\in_array(Resource::TYPE_BACKUP_POLICY, $resources)) {
215215
try {
216216
$scope = 'policies.read';
@@ -1494,32 +1494,42 @@ public function importBackupResource(Resource $resource): Resource
14941494
'schedule' => $resource->getSchedule(),
14951495
];
14961496

1497-
if ($resource->getResourceId()) {
1498-
$collection = match ($resource->getResourceType()) {
1497+
// Validate services - only databases, buckets, and functions are currently supported
1498+
$supportedServices = [Transfer::GROUP_DATABASES, Transfer::GROUP_STORAGE, Transfer::GROUP_FUNCTIONS];
1499+
$unsupportedServices = array_diff($resource->getServices(), $supportedServices);
1500+
if (!empty($unsupportedServices)) {
1501+
throw new Exception(
1502+
resourceName: $resource->getName(),
1503+
resourceGroup: $resource->getGroup(),
1504+
resourceId: $resource->getId(),
1505+
message: 'Unsupported services in backup policy: ' . implode(', ', $unsupportedServices),
1506+
);
1507+
}
1508+
1509+
$resourceType = $resource->getResourceType();
1510+
$resourceId = $resource->getResourceId();
1511+
1512+
if (!empty($resourceId)) {
1513+
// Only databases and buckets support per-resource backup policies
1514+
$collectionMap = [
14991515
Resource::TYPE_DATABASE => 'databases',
15001516
Resource::TYPE_BUCKET => 'buckets',
1501-
default => null,
1502-
};
1517+
];
15031518

1504-
if ($collection !== null) {
1505-
$doc = $this->database->getDocument($collection, $resource->getResourceId());
1519+
if (isset($collectionMap[$resourceType])) {
1520+
// Validate resource exists on destination
1521+
$doc = $this->database->getDocument($collectionMap[$resourceType], $resourceId);
15061522
if ($doc->isEmpty()) {
15071523
throw new Exception(
15081524
resourceName: $resource->getName(),
15091525
resourceGroup: $resource->getGroup(),
15101526
resourceId: $resource->getId(),
1511-
message: 'Referenced ' . $resource->getResourceType() . ' "' . $resource->getResourceId() . '" not found on destination',
1527+
message: 'Referenced ' . $resourceType . ' "' . $resourceId . '" not found on destination',
15121528
);
15131529
}
1514-
1515-
$params['resourceId'] = $resource->getResourceId();
1516-
} elseif ($resource->getResourceType()) {
1517-
// Per-resource backup policies only supported for databases and buckets
1518-
$resource->setStatus(
1519-
Resource::STATUS_WARNING,
1520-
'Per-resource backup policies not supported for resource type: ' . $resource->getResourceType() . '. Created as service-level policy instead.'
1521-
);
15221530
}
1531+
1532+
$params['resourceId'] = $resourceId;
15231533
}
15241534

15251535
$this->call('POST', '/backups/policies', [

src/Migration/Sources/Appwrite.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,12 +1655,13 @@ private function reportBackups(array $resources, array &$report, array $resource
16551655
$body = \json_decode($e->getMessage(), true);
16561656
$code = $body['code'] ?? 0;
16571657

1658-
// Re-throw permission errors as they indicate configuration issues
1658+
// Re-throw permission errors (401/403) as they indicate configuration issues
16591659
if ($code === 401 || $code === 403) {
16601660
throw new \Exception('Missing permission to access backup policies: ' . $e->getMessage(), previous: $e);
16611661
}
16621662

1663-
// Feature not available (404/501) - skip gracefully for self-hosted
1663+
// For other errors (404/501), treat as feature not available - skip gracefully
1664+
// Backup policies are Cloud-only, may not be available on self-hosted
16641665
$report[Resource::TYPE_BACKUP_POLICY] = 0;
16651666
}
16661667
}

0 commit comments

Comments
 (0)