diff --git a/src/Controller/ModulesController.php b/src/Controller/ModulesController.php index c0c880a43..bc7da310f 100644 --- a/src/Controller/ModulesController.php +++ b/src/Controller/ModulesController.php @@ -326,15 +326,23 @@ public function save(): void $response = $this->apiClient->getObject($id, $this->objectType); } if (!$skipSavePermissions) { - $this->savePermissions( - (array)$response, - $schema, - $permissions - ); + try { + $this->savePermissions( + (array)$response, + $schema, + $permissions + ); + } catch (BEditaClientException $error) { + $this->handleError($error); + } } $id = (string)Hash::get($response, 'data.id'); if (!$skipSaveRelated) { - $this->Modules->saveRelated($id, $this->objectType, $relatedData); + try { + $this->Modules->saveRelated($id, $this->objectType, $relatedData); + } catch (BEditaClientException $error) { + $this->handleError($error); + } } $options = [ 'id' => Hash::get($response, 'data.id'), @@ -344,11 +352,7 @@ public function save(): void $event = new Event('Controller.afterSave', $this, $options); $this->getEventManager()->dispatch($event); } catch (BEditaClientException $error) { - $message = new Message($error); - $this->log($message->get(), LogLevel::ERROR); - $this->Flash->error($message->get(), ['params' => $error]); - $this->set(['error' => $message->get()]); - $this->setSerialize(['error']); + $this->handleError($error); return; } @@ -362,6 +366,23 @@ public function save(): void $this->setSerialize(array_keys($response)); } + /** + * Handle exception error: log, flash and set. + * + * @param \BEdita\SDK\BEditaClientException $exception The exception + * @return void + */ + protected function handleError(BEditaClientException $exception): void + { + $message = new Message($exception); + $this->log($message->get(), LogLevel::ERROR); + $this->Flash->error($message->get(), ['params' => $exception]); + $error = $this->viewBuilder()->getVar('error') ?? []; + $error = is_array($error) ? array_merge($error, [$message->get()]) : [$error, $message->get()]; + $this->set(['error' => $error]); + $this->setSerialize(['error']); + } + /** * Clone single object. * @@ -459,10 +480,7 @@ public function related($id, string $relation): void $response = $this->apiClient->getRelated($id, $this->objectType, $relation, $query); $response = $this->ApiFormatter->embedIncluded((array)$response); } catch (BEditaClientException $error) { - $this->log($error->getMessage(), LogLevel::ERROR); - - $this->set(compact('error')); - $this->setSerialize(['error']); + $this->handleError($error); return; } @@ -488,10 +506,7 @@ public function resources($id, string $type): void try { $response = $this->apiClient->get($type, $query); } catch (BEditaClientException $error) { - $this->log($error, LogLevel::ERROR); - - $this->set(compact('error')); - $this->setSerialize(['error']); + $this->handleError($error); return; } diff --git a/tests/TestCase/Controller/ModulesControllerTest.php b/tests/TestCase/Controller/ModulesControllerTest.php index 8e8eae6ac..1581c82b0 100644 --- a/tests/TestCase/Controller/ModulesControllerTest.php +++ b/tests/TestCase/Controller/ModulesControllerTest.php @@ -1315,7 +1315,7 @@ public function testSavePermissions(): void ], 'post' => [ 'id' => 123456789, - 'permissions' => ['1','2','3'], + 'permissions' => ['1', '2', '3'], ], 'params' => [ 'object_type' => 'folders', @@ -1546,4 +1546,62 @@ public function save(string $type, array $data, ?array $headers = null): ?array static::assertTrue($apiClient->getSave(), 'ApiClient save method should be called when no post data is provided'); static::assertFalse($apiClient->getLoad(), 'ApiClient load method should not be called to load object'); } + + /** + * Test errors when saving permissions and related data + * + * @return void + * @covers ::save() + * @covers ::handleError() + */ + public function testSaveErrorPermissionsAndRelatedData(): void + { + $this->setupController(); + $config = [ + 'environment' => [ + 'REQUEST_METHOD' => 'POST', + ], + 'post' => [ + 'title' => 'Test Dummy', + '_api' => [['method' => 'addRelated', 'type' => 'dummies', 'relatedIds' => [['id' => 1, 'type' => 'dummies'], ['id' => 2, 'type' => 'dummies']]]], + 'permissions' => ['1', '2', '3'], + ], + 'params' => [ + 'object_type' => 'documents', + ], + ]; + $request = new ServerRequest($config); + $this->controller = new class ($request) extends ModulesControllerSample + { + public function savePermissions(array $response, array $schema, array $newPermissions): bool + { + throw new BEditaClientException('save permission debug error'); + } + }; + $registry = $this->controller->components(); + $component = new class ($registry) extends ModulesComponent + { + public function skipSavePermissions(string $id, array $requestPermissions, array $schema): bool + { + return false; // do not skip save permissions + } + + public function skipSaveRelated(string $id, array &$relatedData): bool + { + return false; // do not skip save related + } + + public function saveRelated(string $id, string $type, array $relatedData): void + { + throw new BEditaClientException('save related debug error'); + } + }; + $this->controller->Modules = $component; + $this->controller->save(); + $actual = $this->controller->viewBuilder()->getVar('error'); + static::assertIsArray($actual); + static::assertCount(2, $actual); + static::assertStringContainsString('save permission debug error', $actual[0]); + static::assertStringContainsString('save related debug error', $actual[1]); + } }