Skip to content

Commit

Permalink
Merge pull request #12936 from cakephp/issue-12931
Browse files Browse the repository at this point in the history
Improve error messages when persistence fails
  • Loading branch information
markstory committed Jan 30, 2019
2 parents 8b7ffba + 73ee9ed commit 1d82fdd
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 22 deletions.
25 changes: 4 additions & 21 deletions src/ORM/Exception/PersistenceFailedException.php
Expand Up @@ -14,6 +14,7 @@

use Cake\Core\Exception\Exception;
use Cake\Datasource\EntityInterface;
use Cake\Utility\Hash;

/**
* Used when a strict save or delete fails
Expand Down Expand Up @@ -47,35 +48,17 @@ public function __construct(EntityInterface $entity, $message, $code = null, $pr
$this->_entity = $entity;
if (is_array($message)) {
$errors = [];
foreach ($entity->getErrors() as $field => $error) {
$errors[] = $field . ': "' . $this->buildError($error) . '"';
foreach (Hash::flatten($entity->getErrors()) as $field => $error) {
$errors[] = $field . ': "' . $error . '"';
}
if ($errors) {
$message[] = implode(', ', $errors);
$this->_messageTemplate = 'Entity %s failure (%s).';
$this->_messageTemplate = 'Entity %s failure. Found the following errors (%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
*
Expand Down
26 changes: 25 additions & 1 deletion tests/TestCase/ORM/TableTest.php
Expand Up @@ -6414,7 +6414,7 @@ public function testSaveOrFail()
public function testSaveOrFailErrorDisplay()
{
$this->expectException(\Cake\ORM\Exception\PersistenceFailedException::class);
$this->expectExceptionMessage('Entity save failure (field: "Some message", multiple: "one, two")');
$this->expectExceptionMessage('Entity save failure. Found the following errors (field.0: "Some message", multiple.one: "One", multiple.two: "Two")');

$entity = new Entity([
'foo' => 'bar'
Expand All @@ -6426,6 +6426,30 @@ public function testSaveOrFailErrorDisplay()
$table->saveOrFail($entity);
}

/**
* Tests that saveOrFail with nested errors
*
* @return void
*/
public function testSaveOrFailNestedError()
{
$this->expectException(\Cake\ORM\Exception\PersistenceFailedException::class);
$this->expectExceptionMessage('Entity save failure. Found the following errors (articles.0.title.0: "Bad value")');

$entity = new Entity([
'username' => 'bad',
'articles' => [
new Entity(['title' => 'not an entity'])
]
]);
$entity->articles[0]->setError('title', 'Bad value');

$table = $this->getTableLocator()->get('Users');
$table->hasMany('Articles');

$table->saveOrFail($entity);
}

/**
* Tests that saveOrFail returns the right entity
*
Expand Down

0 comments on commit 1d82fdd

Please sign in to comment.