Today I updated from Diff 8.x-1.0-alpha4 to Diff 8.x-1.0-alpha5. I tested it out for a few minutes, from 19:32 to 19:34, so no more than 3 mintures. Now I see my log has been flooded with about 1200 warning messages. They are all like the following:

Type: php
Location: http:///node/54/revisions/view/678/679/single_column
Referrer: http:///node/54/revisions/view/592/678/single_column
Message: Warning: Illegal string offset 'data' in Drupal\diff\Plugin\diff\Layout\SingleColumnDiffLayout->build() (line 156 of /home//public_html/modules/diff/src/Plugin/diff/Layout/SingleColumnDiffLayout.php).
Severity: Warning

Type: php
Location: http:///node/54/revisions/view/678/679/single_column
Referrer: http:///node/54/revisions/view/592/678/single_column
Message: Warning: Illegal string offset '#markup' in Drupal\diff\Plugin\diff\Layout\SingleColumnDiffLayout->build() (line 156 of /home//public_html/modules/diff/src/Plugin/diff/Layout/SingleColumnDiffLayout.php).
Severity: Warning

I use PHP 7.0.10

Comments

dhendriks created an issue. See original summary.

miro_dietiker’s picture

Priority: Normal » Major

Thx for reporting.

I see from checking the code,
- these keys are not defined as APIs or really guaranteed on return values although expected
- we rely on them

Something is completely wrong with our annotation where
\Drupal\diff\DiffEntityComparison::getRows
indicating to return array on annotation, but returns a call indicating string
\Drupal\Component\Diff\DiffFormatter::format

I guess we need to check the doc header annotation and health check the return values.
And / or consider working more with exceptions to deal with unexpected situations.

Promoting for release consideration to clean our APIs.

johnchque’s picture

Status: Active » Needs review
StatusFileSize
new1.15 KB

Can this make the difference?

dhendriks’s picture

Thanks for looking into this issue so quickly.

Looking at the patch from #3, I don't think it's the (full) solution. It is not just '#markup' that may be missing. I also get warnings for 'data', as I noted in my original description. In fact, this is the reason I included two warning entries in that description: I see them for both 'data' and '#markup'. I have not yet seen any warnings for other keys than those two.

miro_dietiker’s picture

Status: Needs review » Needs work

Also, the documentation of the individual methods should really document very cleanly what structure of array returns they guarantee.
And if they don't guarantee, we need to check before accessing.

miro_dietiker’s picture

Priority: Major » Critical

Promoting this to critical for release.

We need to maintain our API boundaries and guarantees and use them well.

johnchque’s picture

Assigned: Unassigned » johnchque

Actually, I could reproduce. Will test and upload a patch soon.

johnchque’s picture

Status: Needs work » Needs review
StatusFileSize
new3.17 KB

Thanks for reporting, the logs were growing exponentially! This should fix it. Also modified a bit some functions.

johnchque’s picture

Version: 8.x-1.0-alpha5 » 8.x-1.x-dev

Oh btw, bug reports go always against the dev version.

dhendriks’s picture

For the patch in #8, you check the existence of 'data', but not '#markup' in the 'data'. As I get warnings for both, I still think both should be checked, where relevant (used).

For instance, looking at a part of the patch from #8:

+        if (!isset($field_diff_rows[$key][1]['data']) || !isset($field_diff_rows[$key][3]['data'])) {
+          continue;
+        }
         if (trim($field_diff_rows[$key][1]['data']['#markup']) != '') {
           if ($field_diff_rows[$key][1]['data'] == $field_diff_rows[$key][3]['data']) {
             $show = TRUE;

The line just after the 3-line addition accesses the '#markup' in the 'data'. This is probably where the second kind of warning I get is coming from, since both warnings are from the same line. However, this may apply elsewhere as well, I don't know. Maybe the following is also used somewhere?

$field_diff_rows[$key][3]['data']['#markup']

Note the '[3]' rather than the '[1]'. Also note that I don't really know anything about the code, and thus I'm just noting a duality that appears to be present between '[1]' and '[3]', of which I have absolutely no idea what they are about...

johnchque’s picture

Did you check applying the last patch? The markup will be there as long as we have a 'data' key. I've tested, since I was the same kind of warnings (both #markup and data) and I've seen the last patch fixes that.
I've seen the 3 and 1 as keys, that's why my code checks both, if not present just "continue". Please check with the last patch and report if it fixes the problem or not.

dhendriks’s picture

I can't currently check the patch from #8, as updating from 8.x-1.0-alpha5 to 8.x-1.0-beta1 completely broke diffs for me, as I reported in issue #2801889: Parameter "filter" for route "diff.revisions_diff" must match... crash. Once that one is solved, I can check this again...

dhendriks’s picture

#2801889: Parameter "filter" for route "diff.revisions_diff" must match... crash is fixed for me, so I can test the patch from #8. But I already wanted to mention that the problem appears to be restricted to the 'Unified fields' diff layout. The 'Visual Inline' and 'Split fields' diff layouts do not appear to suffer from this issue.

dhendriks’s picture

I can confirm that the patch from #8 does indeed solve the problem for me.

johnchque’s picture

Status: Needs review » Reviewed & tested by the community

Thank you @dhendriks! Then this should be RTBC?

dhendriks’s picture

Then this should be RTBC?

'Reviewed & tested by the community' sound right. Let's commit it and change the status to 'fixed', or is that not how it works?

miro_dietiker’s picture

Status: Reviewed & tested by the community » Needs work

I we have no interface because we are dealing with array, we should write what keys exactly we are creating and returning.
A good example on how to do his is hook_requirements:
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension...

And if it's not us defining it, we should refer to a different location with @see.

Also, you are trying to make us commit a workaround for an "edge case" that is not covered in tests. I guarantee this will break again because someone will clean up this code.
From the issue description above i have zero idea what causes the problem except #7 "Actually, I could reproduce. ".
So please try to provide a test about how to create this case or at least explain.

johnchque’s picture

Status: Needs work » Needs review
StatusFileSize
new732 bytes
new3.98 KB
new1.1 KB

Actually is not an edge case, it was happening because I was trying to get info from places where is none.

The last submitted patch, 18: flood_of_warnings_after-2800155-18-test-only.patch, failed testing.

miro_dietiker’s picture

Status: Needs review » Needs work

I thought that this type of error throws notices that lead to test fails anyway.
It's new to me that this needs dblog module enabled.

berdir’s picture

+++ b/src/DiffEntityComparison.php
@@ -191,8 +191,11 @@ class DiffEntityComparison {
    * @return array
-   *   Array of rows usable with theme('table').
+   *   Array of rows usable with theme('table') returned by the core diff
+   *   formatter when format a diff.
    */

theme() doesn't exist anymore. Should say #type table or table render element as that's what we use, not the template directly.

And yes, any kind of PHP notice or warning should result in exceptions in the test. Not sure what's happening

johnchque’s picture

Status: Needs work » Needs review
StatusFileSize
new481 bytes
new3.96 KB
new1.05 KB

Actually the tests can be much shorter. :)

The last submitted patch, 22: flood_of_warnings_after-2800155-22-test-only.patch, failed testing.

berdir’s picture

Doesn't that imply that there are no tests for "Unified fields" right now? Shouldn't we add a bit more than just a assert 200?

johnchque’s picture

Status: Needs review » Needs work

hmmm actually this breaks when a new entity is present in the right side but not in the left side. Will check.

johnchque’s picture

Status: Needs work » Needs review
StatusFileSize
new595 bytes
new4.62 KB
new1.69 KB

Actually the previous patch was breaking the case when an entity is in one revision and not in the other, this should fix it. A review of @dhendriks with the new patch can be also good.

The last submitted patch, 26: flood_of_warnings_after-2800155-26-test-only.patch, failed testing.

dhendriks’s picture

I tried patch from #26. I still get warnings:

Warning: Illegal string offset 'data' in Drupal\diff\Plugin\diff\Layout\UnifiedFieldsDiffLayout->build() (line 152 of /home/[anonymized]/public_html/modules/diff/src/Plugin/diff/Layout/UnifiedFieldsDiffLayout.php).

johnchque’s picture

can you give us an example about when you get warnings, how is the diff displayed? :) please

johnchque’s picture

Tests unchanged. Actually it was obvious that it was going to throw an exception. We also needed to change in there. :) This time should be clean. :)

The last submitted patch, 30: flood_of_warnings_after-2800155-30-test-only.patch, failed testing.

dhendriks’s picture

Tested patch from #30. I get no warnings, and diffs for 'Unified fields' look same as for 'Split fields'.

johnchque’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for reporting back. :)

miro_dietiker’s picture

Status: Reviewed & tested by the community » Fixed
+++ b/src/Plugin/diff/Layout/UnifiedFieldsDiffLayout.php
@@ -148,8 +148,8 @@ class UnifiedFieldsDiffLayout extends DiffLayoutBase {
+        if (isset($field_diff_rows[$key][1]['data']) && trim($field_diff_rows[$key][1]['data']['#markup']) != '') {
+          if ($field_diff_rows[$key][1] == $field_diff_rows[$key][3]) {

@@ -174,8 +174,8 @@ class UnifiedFieldsDiffLayout extends DiffLayoutBase {
+        if ($field_diff_rows[$key][1] != $field_diff_rows[$key][3]) {
+          if (isset($field_diff_rows[$key][3]['data']) && trim($field_diff_rows[$key][3]['data']['#markup']) != '') {

Why are these lines inversed in sequence? :-)

Committed, thx!

johnchque’s picture

Because the first if is to define if we need to add 1 to the row count when there is a value to diff. the second one checks first if there are differences between the values, if so displays a row, otherwise it prevents duplicated lines. :)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.