Symfony 5: An unexpected value could not be normalized: stream resource

Viewed 2015

Code

Entity Class

use Doctrine\ORM\Mapping as ORM;

/**
 * Device
 *
 * @ORM\Table(name="device", uniqueConstraints={@ORM\UniqueConstraint(name="uid", columns={"uid"})}, indexes={@ORM\Index(name="device__visitor_id", columns={"visitor_id"})})
 * @ORM\Entity
 */
class Device
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var binary|null
     *
     * @ORM\Column(name="uid", type="binary", nullable=true, options={"comment"="Agent cookie ID (Cross-site tracking)"})
     */
    private $uid;

    /**
     * @var string
     *
     * @ORM\Column(name="ua", type="string", length=511, nullable=false, options={"comment"="HTTP User agent"})
     */
    private $ua;

    /**
     * @var string|null
     *
     * @ORM\Column(name="os", type="string", length=128, nullable=true, options={"comment"="User operating system (from WhichBrowser)"})
     */
    private $os;

    /**
     * @var string|null
     *
     * @ORM\Column(name="browser_name", type="string", length=128, nullable=true, options={"comment"="Browser name (from WhichBrowser)"})
     */
    private $browserName;

    /**
     * @var string|null
     *
     * @ORM\Column(name="browser", type="string", length=255, nullable=true, options={"comment"="Full browser name (from WhichBrowser)"})
     */
    private $browser;

    /**
     * @var string|null
     *
     * @ORM\Column(name="device_type", type="string", length=32, nullable=true, options={"comment"="Device type (from WhichBrowser)"})
     */
    private $deviceType;

    /**
     * @var string|null
     *
     * @ORM\Column(name="device", type="string", length=128, nullable=true, options={"comment"="Full device name (from WhichBrowser)"})
     */
    private $device;

    /**
     * @var int|null
     *
     * @ORM\Column(name="width", type="integer", nullable=true, options={"comment"="User screen width"})
     */
    private $width;

    /**
     * @var int|null
     *
     * @ORM\Column(name="height", type="integer", nullable=true, options={"comment"="User screen height"})
     */
    private $height;

    /**
     * @var int
     *
     * @ORM\Column(name="c_utime", type="integer", nullable=false, options={"comment"=" Unix time in GMT"})
     */
    private $cUtime;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getUid()
    {
        return $this->uid;
    }

    public function setUid($uid): self
    {
        $this->uid = $uid;

        return $this;
    }

    public function getUa(): ?string
    {
        return $this->ua;
    }

    public function setUa(string $ua): self
    {
        $this->ua = $ua;

        return $this;
    }

    public function getOs(): ?string
    {
        return $this->os;
    }

    public function setOs(?string $os): self
    {
        $this->os = $os;

        return $this;
    }

    public function getBrowserName(): ?string
    {
        return $this->browserName;
    }

    public function setBrowserName(?string $browserName): self
    {
        $this->browserName = $browserName;

        return $this;
    }

    public function getBrowser(): ?string
    {
        return $this->browser;
    }

    public function setBrowser(?string $browser): self
    {
        $this->browser = $browser;

        return $this;
    }

    public function getDeviceType(): ?string
    {
        return $this->deviceType;
    }

    public function setDeviceType(?string $deviceType): self
    {
        $this->deviceType = $deviceType;

        return $this;
    }

    public function getDevice(): ?string
    {
        return $this->device;
    }

    public function setDevice(?string $device): self
    {
        $this->device = $device;

        return $this;
    }

    public function getWidth(): ?int
    {
        return $this->width;
    }

    public function setWidth(?int $width): self
    {
        $this->width = $width;

        return $this;
    }

    public function getHeight(): ?int
    {
        return $this->height;
    }

    public function setHeight(?int $height): self
    {
        $this->height = $height;

        return $this;
    }

    public function getCUtime(): ?int
    {
        return $this->cUtime;
    }

    public function setCUtime(int $cUtime): self
    {
        $this->cUtime = $cUtime;

        return $this;
    }
}

Repository Class

namespace App\Repository;

use App\Entity\Device;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

class DeviceRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Device::class);
    }
}

Controller Class

use App\Repository\DeviceRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class DashboardController extends AbstractController
{
    /**
     * @var DeviceRepository
     */
    private $deviceRepository;

    /**
     * DashboardController constructor.
     * @param DeviceRepository $deviceRepository
     */
    public function __construct(
        DeviceRepository $deviceRepository
    ) {
        $this->deviceRepository = $deviceRepository;
    }

    /**
     * @Route("device/{device_id}/details", name="device.details")
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     */
    public function getDevice(Request $request)
    {
        $id = $request->get('device_id');
        $device = $this->deviceRepository->find($id);

        return $this->json($device);
    }
}

Expected Output

{
    id: 1,
    uid: "<<some string here>>"
    ua: "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Instagram 127.0.0.22.119 (iPhone11,6; iOS 13_3; en_US; en-US; scale=3.00; 1242x2688; 196215991)"
    os: "iOS 13.3"
    browserName: "Instagram"
    browser: "Instagram 127.0.0.22"
    deviceType: "mobile"
    device: "Apple iPhone XS Max"
    width: "414"
    height: "896"
    cUtime: 1581304156
}

Error

500 (Internal Server Error) An unexpected value could not be normalized: stream resource

Stack Trace in Chrome DevTool

{
    type: "https://tools.ietf.org/html/rfc2616#section-10",
    title: "An error occurred", 
    status: 500,
    detail: "An unexpected value could not be normalized: stream resource",
    class: "Symfony\Component\Serializer\Exception\NotNormalizableValueException", 
    trace: {
        {
            namespace: ""
            short_class: ""
            class: ""
            type: ""
            function: ""
            file: "/var/www/html/awtracker/vendor/symfony/serializer/Serializer.php"
            line: 170
        }, {
            namespace: "Symfony\Component\Serializer"
            short_class: "Serializer"
            class: "Symfony\Component\Serializer\Serializer"
            type: "->"
            function: "normalize"
            file: "/var/www/html/awtracker/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php"
            line: 201
        }, {
            namespace: "Symfony\Component\Serializer\Normalizer"
            short_class: "AbstractObjectNormalizer"
            class: "Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer"
            type: "->"
            function: "normalize"
            file: "/var/www/html/awtracker/vendor/symfony/serializer/Serializer.php"
            line: 146
        }, {
            namespace: "Symfony\Component\Serializer"
            short_class: "Serializer"
            class: "Symfony\Component\Serializer\Serializer"
            type: "->"
            function: "normalize"
            file: "/var/www/html/awtracker/vendor/symfony/serializer/Serializer.php"
            line: 119
        }, {
            namespace: "Symfony\Component\Serializer"
            short_class: "Serializer"
            class: "Symfony\Component\Serializer\Serializer"
            type: "->"
            function: "serialize"
            file: "/var/www/html/awtracker/vendor/symfony/framework-bundle/Controller/AbstractController.php"
            line: 174
        }, {
            namespace: "Symfony\Bundle\FrameworkBundle\Controller"
            short_class: "AbstractController"
            class: "Symfony\Bundle\FrameworkBundle\Controller\AbstractController"
            type: "->"
            function: "json"
            file: "/var/www/html/awtracker/src/Controller/DashboardController.php"
            line: 32
        }, {
            short_class: "DashboardController"
            class: "App\Controller\DashboardController"
            type: "->"
            function: "paginate"
            file: "/var/www/html/awtracker/vendor/symfony/http-kernel/HttpKernel.php"
            line: 145
        }, {
            namespace: "Symfony\Component\HttpKernel"
            short_class: "HttpKernel"
            class: "Symfony\Component\HttpKernel\HttpKernel"
            type: "->"
            function: "handleRaw"
            file: "/var/www/html/awtracker/vendor/symfony/http-kernel/HttpKernel.php"
            line: 67
        }, {
            namespace: "Symfony\Component\HttpKernel"
            short_class: "HttpKernel"
            class: "Symfony\Component\HttpKernel\HttpKernel"
            type: "->"
            function: "handle"
            file: "/var/www/html/awtracker/vendor/symfony/http-kernel/Kernel.php"
            line: 191
        }, {
            namespace: "Symfony\Component\HttpKernel"
            short_class: "Kernel"
            class: "Symfony\Component\HttpKernel\Kernel"
            type: "->"
            function: "handle"
            file: "/var/www/html/awtracker/public/index.php"
            line: 25
        }
    }
}

Code is written in Symfony 5 and php 7.2.5. This is an API code, and returned data should be in JSON format. This is a unique error and I couldn't find enough information to solve it.

2 Answers

I have the same problem. It comes from the binary type. Here's what the Doctrine documentation says about this type:

Maps and converts binary string data with a maximum length. If you know that the data to be stored always fits into the specified length, you should consider using this type. Values retrieved from the database are always converted to PHP's resource type or null if no data is present.

In my case, I changed type="binary" to type="boolean" and it worked.

For your case, you might consider to use the GUID data type or to cast in your getter like this:

public function getUid()
{
    return (string) $this->uid;
}

The getter needs an update:

public function getUid(): ?string
{
    return is_resource($this->uid) ? stream_get_contents($this->uid) : $this->uid;
}

In addition to that, you may need to add some trickery to your code, for example:

$device->setUid($device->getUid());

After reading the row from the device table, you may end up having an entity where the type of the uid property is "stream_resource". Calling the setter with the return value of the getter will make it a string.

Related