Handle errors when filtering dynamic segments
When a segment has an invalid filter we don't want that error to break other pages in the MailPoet admin. MAILPOET-5538
This commit is contained in:
committed by
Aschepikov
parent
2a1245bd8a
commit
5972db6a47
@ -9,6 +9,7 @@ use MailPoet\Entities\SubscriberEntity;
|
|||||||
use MailPoet\Entities\SubscriberSegmentEntity;
|
use MailPoet\Entities\SubscriberSegmentEntity;
|
||||||
use MailPoet\InvalidStateException;
|
use MailPoet\InvalidStateException;
|
||||||
use MailPoet\NotFoundException;
|
use MailPoet\NotFoundException;
|
||||||
|
use MailPoet\Segments\DynamicSegments\Exceptions\InvalidFilterException;
|
||||||
use MailPoet\Segments\DynamicSegments\FilterHandler;
|
use MailPoet\Segments\DynamicSegments\FilterHandler;
|
||||||
use MailPoetVendor\Doctrine\DBAL\Connection;
|
use MailPoetVendor\Doctrine\DBAL\Connection;
|
||||||
use MailPoetVendor\Doctrine\DBAL\Driver\Statement;
|
use MailPoetVendor\Doctrine\DBAL\Driver\Statement;
|
||||||
@ -420,7 +421,13 @@ class SegmentSubscribersRepository {
|
|||||||
if (count($filters) === 0) {
|
if (count($filters) === 0) {
|
||||||
return $queryBuilder->andWhere('0 = 1');
|
return $queryBuilder->andWhere('0 = 1');
|
||||||
} elseif ($segment instanceof SegmentEntity) {
|
} elseif ($segment instanceof SegmentEntity) {
|
||||||
$queryBuilder = $this->filterHandler->apply($queryBuilder, $segment);
|
try {
|
||||||
|
$queryBuilder = $this->filterHandler->apply($queryBuilder, $segment);
|
||||||
|
} catch (InvalidFilterException $e) {
|
||||||
|
// If a segment has an invalid filter, we should simply consider it empty instead of throwing
|
||||||
|
// an unhandled error. Unhandled errors here can break many admin pages.
|
||||||
|
$queryBuilder->andWhere('0 = 1');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
$queryBuilder = $queryBuilder->andWhere("$subscribersTable.deleted_at IS NULL");
|
$queryBuilder = $queryBuilder->andWhere("$subscribersTable.deleted_at IS NULL");
|
||||||
|
@ -229,6 +229,22 @@ class SegmentSubscribersRepositoryTest extends \MailPoetTest {
|
|||||||
verify($countWithFilter)->equals(2);
|
verify($countWithFilter)->equals(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSubscriberCountIsZeroIfItHasAnInvalidFilter(): void {
|
||||||
|
$segment = new SegmentEntity('Segment' . rand(0, 10000), SegmentEntity::TYPE_DYNAMIC, 'Segment description');
|
||||||
|
$filterData = new DynamicSegmentFilterData(
|
||||||
|
'typeThatDefinitelyDoesNotExist',
|
||||||
|
'theActionDoesNotExistEither'
|
||||||
|
);
|
||||||
|
$dynamicFilter = new DynamicSegmentFilterEntity($segment, $filterData);
|
||||||
|
$segment->getDynamicFilters()->add($dynamicFilter);
|
||||||
|
$this->entityManager->persist($segment);
|
||||||
|
$this->entityManager->persist($dynamicFilter);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$count = $this->repository->getSubscribersCountBySegmentIds([$segment->getId()]);
|
||||||
|
$this->assertEquals(0, $count);
|
||||||
|
}
|
||||||
|
|
||||||
public function _after() {
|
public function _after() {
|
||||||
parent::_after();
|
parent::_after();
|
||||||
$this->cleanup();
|
$this->cleanup();
|
||||||
|
Reference in New Issue
Block a user