10
votes

I have some code which has broken somewhere along the way and I'm having trouble debugging it.

This is a simplified version of it.

$data = $this->request->data;

$form = $this->Forms->get($data['id'], [
    'contain' => ['FieldsForms' => ['data']
    ]
]);

$form = $this->Forms->patchEntity($form, $data,
    ['associated' => [
        'FieldsForms.Data',

    ]
]);

if ($this->Forms->save($form)) {
    // sunshine and rainbows
} else {
    // wailing and gnashing of teeth
}

I'm left wailing and gnashing teeth without any errors, as far as I can see if I debug the $data it looks like it's ok (though since it's fairly long and contains a bunch of UUIDs it's possible I'm missing something).

Validation errors is empty.

The save is returning false - any suggestions on how to debug this might save what sanity I have left.

Thanks!

4
When you are saying "Validation errors is empty", how do you check that? After saving so that possible table rule errors are included? - ndm
The view is rendered and using debug kit it shows validation for 'form' as empty - Rich Hobbs
Then I'd suggest digging into the CakePHP core source to debug the control flow that originates from the Table::save() call. - ndm

4 Answers

19
votes

The problem turned out to be the data, as expected but couldn't see immediately because the save was returning false and the data was quite large.

I first made a subset of the problem data which displayed the same behaviour then, following ndm's suggestion, changed the ORM/Table.php code for the save function as follows to be able to see where the problem was:

// $entity->errors() is deprecated as of CakePHP 3.7
// $entity->getErrors() should be used in later versions
$x = $entity->errors();
if ($x) {
    debug($entity);
    debug($x);
    return false;
}

So that I could see what was going on and went on to fix the data.

5
votes

Not sure if the earlier answer is based on an older version, but in the latest cakephp version (3.4) you can retrieve the errors directly from the $entity within the controller. The errors array contains each entity field that failed, with a child array of failed validations.

<?php
// In Articles Controller
...

public function add(){
...
  if ($this->Articles->save($article)) {
    $this->Flash->success(__('The Article has been saved.'));
    return $this->redirect(['action' => 'index']);
  } else {
    Log::Debug($article->errors());
  }
0
votes

Instead modify the core Cake code you can do this:

if ($this->Forms->save($form)) {
    // sunshine and rainbows
} else {
    //you know now what fail
    $andTheErrorsAre = $entity->getErrors();
}
0
votes

For CakePHP 3.4.*

Try this code:

if (!$this->Forms->save($form)) {
    $this->log($form->getErrors(),'error');
}

Read more about logs here: https://book.cakephp.org/3.0/en/core-libraries/logging.html#using-the-filelog-adapter