Browse Source

Fix saveOrFail() to include useful messages on output, e.g. CLI/tests.

dereuromark 8 years ago
parent
commit
c6be0ab87b
2 changed files with 51 additions and 0 deletions
  1. 29 0
      src/ORM/Exception/PersistenceFailedException.php
  2. 22 0
      tests/TestCase/ORM/TableTest.php

+ 29 - 0
src/ORM/Exception/PersistenceFailedException.php

@@ -45,10 +45,38 @@ class PersistenceFailedException extends Exception
     public function __construct(EntityInterface $entity, $message, $code = null, $previous = null)
     {
         $this->_entity = $entity;
+        if (is_array($message)) {
+            $errors = [];
+            foreach ($entity->getErrors() as $field => $error) {
+                $errors[] = $field . ': "' . $this->buildError($error) . '"';
+            }
+            if ($errors) {
+                $message[] = implode(', ', $errors);
+                $this->_messageTemplate = 'Entity %s failure (%s).';
+            }
+        }
         parent::__construct($message, $code, $previous);
     }
 
     /**
+     * @param string|array $error Error message.
+     * @return string
+     */
+    protected function buildError($error)
+    {
+        if (!is_array($error)) {
+            return $error;
+        }
+
+        $errors = [];
+        foreach ($error as $key => $message) {
+            $errors[] = is_int($key) ? $message : $key;
+        }
+
+        return implode(', ', $errors);
+    }
+
+    /**
      * Get the passed in entity
      *
      * @return \Cake\Datasource\EntityInterface
@@ -57,4 +85,5 @@ class PersistenceFailedException extends Exception
     {
         return $this->_entity;
     }
+
 }

+ 22 - 0
tests/TestCase/ORM/TableTest.php

@@ -6519,6 +6519,28 @@ class TableTest extends TestCase
     }
 
     /**
+     * Tests that saveOrFail displays useful messages on output, especially in tests for CLI.
+     *
+     * @return void
+     */
+    public function testSaveOrFailErrorDisplay()
+    {
+        $this->expectException(\Cake\ORM\Exception\PersistenceFailedException::class);
+        $this->expectExceptionMessage('Entity save failure (field: "Some message", multiple: "one, two")');
+        $entity = new Entity([
+            'foo' => 'bar'
+        ]);
+        $entity->setError('field', 'Some message');
+        $entity->setError('multiple', ['one' => 'One', 'two' => 'Two']);
+        $table = TableRegistry::get('users');
+
+        $table->saveOrFail($entity);
+
+        $row = $table->find('all')->where(['foo' => 'bar'])->toArray();
+        $this->assertSame([], $row->toArray());
+    }
+
+    /**
      * Tests that saveOrFail returns the right entity
      *
      * @return void