mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Capture error on real-time update when creating short URL
This commit is contained in:
37
module/Core/src/ShortUrl/Model/UrlShorteningResult.php
Normal file
37
module/Core/src/ShortUrl/Model/UrlShorteningResult.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\ShortUrl\Model;
|
||||
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||
use Throwable;
|
||||
|
||||
final class UrlShorteningResult
|
||||
{
|
||||
private function __construct(
|
||||
public readonly ShortUrl $shortUrl,
|
||||
private readonly ?Throwable $errorOnEventDispatching,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(Throwable $errorOnEventDispatching): void $handler
|
||||
*/
|
||||
public function onEventDispatchingError(callable $handler): void
|
||||
{
|
||||
if ($this->errorOnEventDispatching !== null) {
|
||||
$handler($this->errorOnEventDispatching);
|
||||
}
|
||||
}
|
||||
|
||||
public static function withoutErrorOnEventDispatching(ShortUrl $shortUrl): self
|
||||
{
|
||||
return new self($shortUrl, null);
|
||||
}
|
||||
|
||||
public static function withErrorOnEventDispatching(ShortUrl $shortUrl, Throwable $errorOnEventDispatching): self
|
||||
{
|
||||
return new self($shortUrl, $errorOnEventDispatching);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\Core\ShortUrl;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlCreated;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
@@ -13,6 +14,7 @@ use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortCodeUniquenessHelperInterface;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlTitleResolutionHelperInterface;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
|
||||
|
||||
@@ -31,12 +33,12 @@ class UrlShortener implements UrlShortenerInterface
|
||||
* @throws NonUniqueSlugException
|
||||
* @throws InvalidUrlException
|
||||
*/
|
||||
public function shorten(ShortUrlCreation $creation): ShortUrl
|
||||
public function shorten(ShortUrlCreation $creation): UrlShorteningResult
|
||||
{
|
||||
// First, check if a short URL exists for all provided params
|
||||
$existingShortUrl = $this->findExistingShortUrlIfExists($creation);
|
||||
if ($existingShortUrl !== null) {
|
||||
return $existingShortUrl;
|
||||
return UrlShorteningResult::withoutErrorOnEventDispatching($existingShortUrl);
|
||||
}
|
||||
|
||||
$creation = $this->titleResolutionHelper->processTitleAndValidateUrl($creation);
|
||||
@@ -51,9 +53,17 @@ class UrlShortener implements UrlShortenerInterface
|
||||
return $shortUrl;
|
||||
});
|
||||
|
||||
$this->eventDispatcher->dispatch(new ShortUrlCreated($newShortUrl->getId()));
|
||||
try {
|
||||
$this->eventDispatcher->dispatch(new ShortUrlCreated($newShortUrl->getId()));
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
// Ignore container errors when dispatching the event.
|
||||
// When using openswoole, this event will try to enqueue a task, which cannot be done outside an HTTP
|
||||
// request.
|
||||
// If the short URL is created from CLI, the event dispatching will fail.
|
||||
return UrlShorteningResult::withErrorOnEventDispatching($newShortUrl, $e);
|
||||
}
|
||||
|
||||
return $newShortUrl;
|
||||
return UrlShorteningResult::withoutErrorOnEventDispatching($newShortUrl);
|
||||
}
|
||||
|
||||
private function findExistingShortUrlIfExists(ShortUrlCreation $creation): ?ShortUrl
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\Core\ShortUrl;
|
||||
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult;
|
||||
|
||||
interface UrlShortenerInterface
|
||||
{
|
||||
@@ -15,5 +15,5 @@ interface UrlShortenerInterface
|
||||
* @throws NonUniqueSlugException
|
||||
* @throws InvalidUrlException
|
||||
*/
|
||||
public function shorten(ShortUrlCreation $creation): ShortUrl;
|
||||
public function shorten(ShortUrlCreation $creation): UrlShorteningResult;
|
||||
}
|
||||
|
||||
@@ -58,9 +58,9 @@ class UrlShortenerTest extends TestCase
|
||||
)->willReturnArgument(0);
|
||||
$this->shortCodeHelper->method('ensureShortCodeUniqueness')->willReturn(true);
|
||||
|
||||
$shortUrl = $this->urlShortener->shorten($meta);
|
||||
$result = $this->urlShortener->shorten($meta);
|
||||
|
||||
self::assertEquals($longUrl, $shortUrl->getLongUrl());
|
||||
self::assertEquals($longUrl, $result->shortUrl->getLongUrl());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -91,7 +91,7 @@ class UrlShortenerTest extends TestCase
|
||||
|
||||
$result = $this->urlShortener->shorten($meta);
|
||||
|
||||
self::assertSame($expected, $result);
|
||||
self::assertSame($expected, $result->shortUrl);
|
||||
}
|
||||
|
||||
public static function provideExistingShortUrls(): iterable
|
||||
|
||||
Reference in New Issue
Block a user