Trying to export a contact form while running PHP 7.3 fails. The error reported is:
Notice: unserialize(): Error at offset 45695 of 62137 bytes in Drupal\Core\Batch\BatchStorage->load()

Comments

simon_tma created an issue. See original summary.

scott_euser’s picture

Are you sure that is PHP 7.3? Seems likely some particular field or record is failing to export. If you create a simple form with lets say just a text field, and something something like Test123, does it export?

This module actually uses csv_serialization module to handle the serialization for the CSV, but without the actual data it is likely going to be hard to reproduce this issue. Also if you could turn on verbose error reporting (ie, add '$config['system.logging']['error_level'] = 'verbose';' to settings.php) and send the full report from admin/reports/dblog - essentially looking for the stack trace which is the list of functions / files that were called before that as that error points to an action taken by Drupal Core.

So I think next steps are:

  1. Provide full error report
  2. Try this out with a simple form to ensure it is actually related to particular results
  3. If it is particular results, we can speak about getting some of the data (anonymized) to try to reproduce
simon_tma’s picture

Notice: unserialize(): Error at offset 45708 of 75470 bytes in Drupal\Core\Batch\BatchStorage->load() (line 71 of /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/Batch/BatchStorage.php)
#0 /Users/simon/projects/ncetp-d8-website/core/includes/bootstrap.inc(584): _drupal_error_handler_real(8, 'unserialize(): ...', '/Users/simon/pr...', 71, Array)
#1 [internal function]: _drupal_error_handler(8, 'unserialize(): ...', '/Users/simon/pr...', 71, Array)
#2 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/Batch/BatchStorage.php(71): unserialize('a:12:{s:4:"sets...')
#3 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/ProxyClass/Batch/BatchStorage.php(75): Drupal\Core\Batch\BatchStorage->load('281')
#4 /Users/simon/projects/ncetp-d8-website/core/includes/batch.inc(43): Drupal\Core\ProxyClass\Batch\BatchStorage->load('281')
#5 /Users/simon/projects/ncetp-d8-website/core/modules/system/src/Controller/BatchController.php(55): _batch_page(Object(Symfony\Component\HttpFoundation\Request))
#6 [internal function]: Drupal\system\Controller\BatchController->batchPage(Object(Symfony\Component\HttpFoundation\Request))
#7 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#8 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#9 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#10 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#11 /Users/simon/projects/ncetp-d8-website/vendor/symfony/http-kernel/HttpKernel.php(151): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#12 /Users/simon/projects/ncetp-d8-website/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#13 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /Users/simon/projects/ncetp-d8-website/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /Users/simon/projects/ncetp-d8-website/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /Users/simon/projects/ncetp-d8-website/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /Users/simon/projects/ncetp-d8-website/core/lib/Drupal/Core/DrupalKernel.php(693): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /Users/simon/projects/ncetp-d8-website/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#22 /Users/simon/projects/ncetp-d8-website/.ht.router.php(65): require('/Users/simon/pr...')
#23 {main}.

The full error's probably not that useful as it's just trying to load in the batch action. Other batch actions work, so it's not specifically about batch actions.

Creating a new form, submitting a single submission with the message "Test" and submitter set to a user then exporting fails again. Switching PHP back to PHP 7.2 has this new form exporting fine (I'm using `php -S` for these tests, but we've seen similar behaviour on our production servers)

simon_tma’s picture

StatusFileSize
new51.33 KB

I've attached what's being attempted to be unserialised from the test form (the `batch` field from the `batch` table)

scott_euser’s picture

Status: Active » Closed (cannot reproduce)

Hmmm it doesn't seem to point at any code from Contact Storage Export. This module utilises CSV Serialization module to handle that (https://www.drupal.org/project/csv_serialization). Perhaps this issue should move there.

nikral’s picture

I have the same Problem,

Notice: unserialize(): Error at offset 53202 of 70123 bytes in Drupal\Core\Batch\BatchStorage->load() (line 71 of core/lib/Drupal/Core/Batch/BatchStorage.php).
Drupal\Core\Batch\BatchStorage->load('90') (Line: 75)
Drupal\Core\ProxyClass\Batch\BatchStorage->load('90') (Line: 43)
_batch_page(Object) (Line: 55)
Drupal\system\Controller\BatchController->batchPage(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Aucun traitement par lot actif.
scott_euser’s picture

Hi Nikral,

Thanks for your comment.

As per #2, I will need more details to be able to help you at all.

But as per #5 it is very likely that the issue is not with this module, but with the module that handles the serialisation (given the error message is Notice: unserialize(): Error at offset 53202 of 70123 bytes) which is csv_serialization.

Thanks,
Scott

boshtian’s picture

scott_euser it is a problem with serialization, but not csv_serialization but serialization that is done while preparing a batch operation, which is in core. After we discovered this issue on our project we tested it on a fresh Drupal 8 install (8.8.2) using PHP 7.3 and we also encountered the problem described above.

There is already an issue for this: https://www.drupal.org/project/drupal/issues/3055287. After applying the latest patch in the issue (#20), exports started to work.

scott_euser’s picture

Thanks for digging into that! I am sure your find will come in handy for someone else in the future. Added as a related issue.

andras_szilagyi’s picture

Version: 8.x-1.12 » 8.x-1.x-dev
Status: Closed (cannot reproduce) » Needs review
StatusFileSize
new2.79 KB

Hate to be that guy that reopens tickets, I've read https://www.drupal.org/project/drupal/issues/3055287 as explained in #8 its not a common scenario, there does not seem to be a clear consensus on the solution and more work is needed, so it might take a while for it to be fixed.

In our case the issue seems to be the Request object that triggers the issue, I suggest this patch that works around that, so we have the fix here now.

btw to reproduce its really easy, just try to export under php7.3 you will get error batch not found, and if you check the logs you will see the unserialize notice.

scott_euser’s picture

Thanks for your feedback. I am able to export on 7.3 on my local and export via automated tests are also passing on 7.3: https://www.drupal.org/node/2752613/qa so I do think we need more information about how to reproduce. I am guessing the solution in the related issue did not solve it for you then? How does removing the request object solve this?

Essentially the issue must be reproducible somehow, and if so, we can add a test that shows it is not working correctly with corresponding code to fix the issue.

scott_euser’s picture

Status: Needs review » Postponed (maintainer needs more info)
andras_szilagyi’s picture

StatusFileSize
new2.13 KB

adding test for issue, hoping this will fail...

andras_szilagyi’s picture

Good, failed with Exception: Notice: unserialize(): Error at offset 38407 of 53502 bytes (https://www.drupal.org/pift-ci-job/1649697)

andras_szilagyi’s picture

StatusFileSize
new4.92 KB

And this should now prove the fix, fingers crossed..

andras_szilagyi’s picture

Status: Postponed (maintainer needs more info) » Needs review

Hi @scott_euser,

in #13 I provided a patch which reproduces the issue, I used a browser test with form submission to trigger the error (as it is in the user interface).

in #15 I merged #10 with #13 to show that my original patch solves the issue.

Please review, let me know if you want anything changed.

Thanks.

ben.hamelin’s picture

Patch in #15 resolved the issue for us. Recently upgraded to PHP 7.3 and started seeing this.
Thanks all!

mojiferous’s picture

I just encountered this too using PHP 7.3 - it's definitely fixed by the patch in #15. One alternative to patching to use a different request class would be to only pass necessary data into the batch process instead of the entire form_state values.

I believe the issue is that the full values array includes references to classes and data types - the names of these classes and datatypes are sometimes serialized with NULL (ascii 00) characters surrounding an asterisk. I don't exactly know why, but as an example a batch without the patch had values like s:10:"<NUL>*<NUL>options" in my database. PHP's unserialize trimmed <NUL>*<NUL>options into *options and the byte count went from 10 to 8.

Refactoring this batch to pass a simple associative array with only the values needed for the process would also solve this issue.

rymcveigh’s picture

We've tested the patch in #15 as well and can confirm that it resolves the issue.

andras_szilagyi’s picture

Status: Needs review » Reviewed & tested by the community

scott_euser’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for the patch - works for me as well! Thanks also for the suggestions Mojiferous - I'll keep the change simple for now to get it fixed and could consider some refactoring in the future to pass less to the batch.

Status: Fixed » Closed (fixed)

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