Skip to content
This repository has been archived by the owner on Jun 2, 2023. It is now read-only.

Commit

Permalink
Exceptions for json_decode
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonTrekov committed Jun 14, 2019
1 parent 451f620 commit fe985e1
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 16 deletions.
9 changes: 7 additions & 2 deletions src/Consumer.php
Expand Up @@ -63,9 +63,14 @@ public function __construct(
*/
public function execute(AMQPMessage $message): int
{
$data = json_decode($message->body, true);

try {
$data = json_decode($message->body, true);
$jsonErrorCode = json_last_error();

if (JSON_ERROR_NONE !== $jsonErrorCode) {
throw new UnexpectedValueException('json_decode error: ' . json_last_error_msg(), $jsonErrorCode);
}

if (!isset($data['id'])) {
throw new UnexpectedValueException(ConstantMessage::AMQP_DATA_DAMAGED);
}
Expand Down
17 changes: 16 additions & 1 deletion src/Factory/EntityFactory.php
Expand Up @@ -6,6 +6,7 @@

use JMS\Serializer\SerializerInterface;
use Lamoda\QueueBundle\Entity\QueueEntityInterface;
use Lamoda\QueueBundle\Exception\UnexpectedValueException;
use Lamoda\QueueBundle\QueueInterface;

class EntityFactory implements EntityFactoryInterface
Expand All @@ -22,15 +23,29 @@ public function __construct(SerializerInterface $serializer, string $entityClass
$this->entityClass = $entityClass;
}

/**
* @param QueueInterface $queueable
*
* @throws UnexpectedValueException
*
* @return QueueEntityInterface
*/
public function createQueue(QueueInterface $queueable): QueueEntityInterface
{
$name = $queueable->getQueue();
$exchange = $queueable->getExchange();
$jobName = get_class($queueable);
$data = $this->serializer->serialize($queueable, 'json');

$data = json_decode($data, true);
$jsonErrorCode = json_last_error();

if (JSON_ERROR_NONE !== $jsonErrorCode) {
throw new UnexpectedValueException('json_decode error: ' . json_last_error_msg(), $jsonErrorCode);
}

/** @var QueueEntityInterface $queueEntity */
$queueEntity = new $this->entityClass($name, $exchange, $jobName, json_decode($data, true));
$queueEntity = new $this->entityClass($name, $exchange, $jobName, $data);

if (null !== $queueable->getScheduleAt()) {
$queueEntity->setScheduled($queueable->getScheduleAt());
Expand Down
6 changes: 6 additions & 0 deletions src/Factory/PublisherFactory.php
Expand Up @@ -7,6 +7,7 @@
use Lamoda\QueueBundle\ConstantMessage;
use Lamoda\QueueBundle\Entity\QueueEntityInterface;
use Lamoda\QueueBundle\Exception\RuntimeException;
use Lamoda\QueueBundle\Exception\UnexpectedValueException;
use Lamoda\QueueBundle\Publisher;
use Lamoda\QueueBundle\QueueInterface;
use Lamoda\QueueBundle\Service\DelayService;
Expand Down Expand Up @@ -67,6 +68,11 @@ public function get(string $exchangeName): Publisher
return $this->publishers[$exchangeName];
}

/**
* @param QueueInterface $queueable
*
* @throws UnexpectedValueException
*/
public function publish(QueueInterface $queueable): void
{
$exchangeName = $queueable->getExchange();
Expand Down
8 changes: 8 additions & 0 deletions src/Publisher.php
Expand Up @@ -5,6 +5,7 @@
namespace Lamoda\QueueBundle;

use Lamoda\QueueBundle\Entity\QueueEntityInterface;
use Lamoda\QueueBundle\Exception\UnexpectedValueException;
use Lamoda\QueueBundle\Service\DelayService;
use Lamoda\QueueBundle\Service\QueueService;
use OldSound\RabbitMqBundle\RabbitMq\Producer;
Expand Down Expand Up @@ -40,6 +41,13 @@ public function __construct(
$this->delayService = $delayService;
}

/**
* @param QueueInterface $queueable
*
* @throws UnexpectedValueException
*
* @return Publisher
*/
public function prepareJobForPublish(QueueInterface $queueable): self
{
$this->prepareQueueForPublish(
Expand Down
7 changes: 7 additions & 0 deletions src/Service/QueueService.php
Expand Up @@ -122,6 +122,13 @@ public function getToRepublish(int $limit, ?int $offset = null): array
return $this->repository->getToRepublish($limit, $offset);
}

/**
* @param QueueInterface $queueable
*
* @throws UnexpectedValueException
*
* @return QueueEntityInterface
*/
public function createQueue(QueueInterface $queueable): QueueEntityInterface
{
return $this->save($this->entityFactory->createQueue($queueable));
Expand Down
34 changes: 21 additions & 13 deletions tests/unit/ConsumerTest.php
Expand Up @@ -150,10 +150,17 @@ public function testExecute(QueueEntityInterface $queueEntity, AMQPMessage $mess
$this->assertEquals($result, $mockConsumer->execute($message));
}

public function dataExecuteBrokenMessage(): array
public function dataExecute(): array
{
$id = 1;

return [
[$this->getMessage(['name' => 'name'])],
[
$this->getQueue(),
$this->getMessage(json_encode(['id' => $id])),
Consumer::MSG_ACK,
$id,
],
];
}

Expand All @@ -164,11 +171,12 @@ public function dataExecuteBrokenMessage(): array
*
* @dataProvider dataExecuteBrokenMessage()
*/
public function testExecuteBrokenMessage(AMQPMessage $message): void
public function testExecuteBrokenMessage(AMQPMessage $message, string $expectedErrorMessage): void
{
$mockLogger = $this->getMockLogger(['alert']);
$mockLogger->expects($this->once())
->method('alert');
->method('alert')
->with($expectedErrorMessage);

$mockConsumer = $this->getMockConsumer(['doExecute']);

Expand All @@ -179,16 +187,16 @@ public function testExecuteBrokenMessage(AMQPMessage $message): void
$this->assertEquals($mockConsumer::MSG_REJECT, $mockConsumer->execute($message));
}

public function dataExecute(): array
public function dataExecuteBrokenMessage(): array
{
$id = 1;

return [
[
$this->getQueue(),
$this->getMessage(['id' => $id]),
Consumer::MSG_ACK,
$id,
$this->getMessage(json_encode(['name' => 'name'])),
'Data was damaged. Remove message from queue',
],
[
$this->getMessage('abrakadabra'),
'json_decode error: Syntax error',
],
];
}
Expand Down Expand Up @@ -255,7 +263,7 @@ protected function getQueue(): QueueEntityInterface
return $queue;
}

protected function getMessage(array $data = ['id' => 1]): AMQPMessage
protected function getMessage(string $data = '{"id": 1}'): AMQPMessage
{
/** @var \PhpAmqpLib\Channel\AMQPChannel | \PHPUnit_Framework_MockObject_MockObject $channelMock */
$channelMock = $this->getMockBuilder(AMQPChannel::class)
Expand All @@ -272,7 +280,7 @@ protected function getMessage(array $data = ['id' => 1]): AMQPMessage
'channel' => $channelMock,
'delivery_tag' => uniqid(),
];
$message->setBody(json_encode($data));
$message->setBody($data);

return $message;
}
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/Factory/EntityFactoryTest.php
Expand Up @@ -6,6 +6,7 @@

use JMS\Serializer\SerializerInterface;
use Lamoda\QueueBundle\Entity\QueueEntityInterface;
use Lamoda\QueueBundle\Exception\UnexpectedValueException;
use Lamoda\QueueBundle\Factory\EntityFactory;
use Lamoda\QueueBundle\Job\AbstractJob;
use Lamoda\QueueBundle\Tests\Unit\Job\StubJob;
Expand Down Expand Up @@ -59,6 +60,21 @@ public function dataCreateQueue(): array
];
}

public function testJsonDecodeError(): void
{
$this->expectException(UnexpectedValueException::class);
$this->expectExceptionCode(4);
$this->expectExceptionMessage('json_decode error: Syntax error');

$serializer = $this->getJMSSerializer(['serialize']);
$serializer->expects($this->once())
->method('serialize')
->willReturn('abrakadabra');

$factory = $this->createFactory($serializer);
$factory->createQueue(new StubJob(1));
}

private function createFactory(SerializerInterface $serializer): EntityFactory
{
return new EntityFactory($serializer, QueueEntity::class);
Expand Down

0 comments on commit fe985e1

Please sign in to comment.