One of the trickiest errors I’ve found when Migrating Magento 1 to Magento 2 (2.3) has been an issue related to unserialization. There are 2 types of messages I received:

Notice: unserialize(): Error at offset 48 of 60 bytes in 
/.../src/vendor/magento/data-migration-tool/src/Migration/Handler/SerializeToJson/SalesOrderItem.php on line 82
[WARNING]: Could not unserialize data of 
sales_flat_order_item.product_options with record id 5113

Reason: in both cases, the reason is that some data that was stored serialized in the Magento 1 database, had been serialized incorrectly. In this particular case, the issue was related to the item product_options value (there is where custom options selected by the customer are stored when purchasing a product which has custom options).

The wrong solution: fixing the serialized string

Don’t try to fix the serialization issue. Many devs have reported this type of issue (like here). There was also a serialization issue in Magento when upgrading to Magento 2.2. This lend me to a false clue where I tried to fix my serialized string in many different ways as described in this great thread in Stackoverflow.

But the serialized string was impossible to fix. Some information would be lost or the proposed fixes wouldn’t work. Don’t go for that solution.

The good solution: try and catch

After hours of debugging I understood that:

  • The serialization issue affected only some of the order items (out of thousand of orders)
  • The wrong serialized strings were impossible to fix

I analyzed the class that was throwing the error:

src/Migration/Handler/SerializeToJson/SalesOrderItem.php

And I added a try / catch where the error was being thrown.

Solution

You need to edit a file in the data-migration-tool module. Usually you will find it under:

src/vendor/magento/data-migration-tool/src/Migration/Handler/SerializeToJson/SalesOrderItem.php

You need to add a try catch around the line which try to unserialize the option_value string in line 81. From this:

$optionValue = $option['option_value'] ? unserialize($option['option_value']) :
                            $option['option_value'];

To this:

try {
    $optionValue = $option['option_value'] ? unserialize($option['option_value']) : $option['option_value'];
} catch (\Exception $exception) {
    if (!$this->ignoreBrokenData) {
        throw new \Exception($exception);
    }
    $this->logger->warning(sprintf(
        'Could not unserialize data of %s.%s with record id %s',
        $recordToHandle->getDocument()->getName(),
        $this->field,
        $recordToHandle->getValue($this->documentIdFiled->getFiled($recordToHandle->getDocument()))
    ));
    $this->logger->warning("\n");
    $recordToHandle->setValue($this->field, null);
    return;
}

With this solution you will just not import the custom options that were wrongly serialized in Magento 1 (note that in Magento 1 those options were broken too).


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.