Skip to content

Commit

Permalink
Add an error URI resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
mbabker committed Dec 13, 2023
1 parent caf0035 commit 6591f2c
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 2 deletions.
34 changes: 34 additions & 0 deletions src/WAMP/DefaultErrorUriResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

namespace BabDev\WebSocket\Server\WAMP;

use BabDev\WebSocket\Server\WAMP\Middleware\DispatchMessageToHandler;

/**
* The error URI resolver is responsible for resolving URIs for identifying errors,
* which is provided as part of the "CALLERROR" WAMP message to the client.
*/
final readonly class DefaultErrorUriResolver implements ErrorUriResolver
{
/**
* Resolve the error URI or CURIE for the given error type.
*
* Because the types of errors will be application dependent other than the "handler not found"
* scenario in the default {@see DispatchMessageToHandler} middleware, a predefined list of error
* types is not provided by this library. However, implementations should at a minimum support the
* "not-found" type, and must return a generic type if they do not support creating a URI for a
* specific type of error.
*
* @param non-empty-string $errorType
*
* @return non-empty-string
*/
public function resolve(string $errorType): string
{
if ($errorType === 'not-found') {
return 'https://example.com/error#not-found';
}

return 'https://example.com/error#generic';
}
}
27 changes: 27 additions & 0 deletions src/WAMP/ErrorUriResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types=1);

namespace BabDev\WebSocket\Server\WAMP;

use BabDev\WebSocket\Server\WAMP\Middleware\DispatchMessageToHandler;

/**
* The error URI resolver is responsible for resolving URIs for identifying errors,
* which is provided as part of the "CALLERROR" WAMP message to the client.
*/
interface ErrorUriResolver
{
/**
* Resolve the error URI or CURIE for the given error type.
*
* Because the types of errors will be application dependent other than the "handler not found"
* scenario in the default {@see DispatchMessageToHandler} middleware, a predefined list of error
* types is not provided by this library. However, implementations should at a minimum support the
* "not-found" type, and must return a generic type if they do not support creating a URI for a
* specific type of error.
*
* @param non-empty-string $errorType
*
* @return non-empty-string
*/
public function resolve(string $errorType): string;
}
7 changes: 5 additions & 2 deletions src/WAMP/Middleware/DispatchMessageToHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use BabDev\WebSocket\Server\RPCMessageMiddleware;
use BabDev\WebSocket\Server\TopicMessageHandler;
use BabDev\WebSocket\Server\TopicMessageMiddleware;
use BabDev\WebSocket\Server\WAMP\DefaultErrorUriResolver;
use BabDev\WebSocket\Server\WAMP\ErrorUriResolver;
use BabDev\WebSocket\Server\WAMP\Exception\CannotInstantiateMessageHandler;
use BabDev\WebSocket\Server\WAMP\Exception\InvalidMessageHandler;
use BabDev\WebSocket\Server\WAMP\Exception\InvalidRequest;
Expand Down Expand Up @@ -47,6 +49,7 @@ public function __construct(
private UrlMatcherInterface $matcher,
private MessageHandlerResolver $resolver,
private ?EventDispatcherInterface $dispatcher = null,
private ErrorUriResolver $errorUriResolver = new DefaultErrorUriResolver(),
) {}

/**
Expand Down Expand Up @@ -110,7 +113,7 @@ public function onCall(WAMPConnection $connection, string $id, string $resolvedU
} catch (RouteNotFound $exception) {
$connection->callError(
$id,
'https://example.com/error#not-found', // TODO - Make the error URI customizable
$this->errorUriResolver->resolve('not-found'),
sprintf('Could not find a message handler for URI "%s".', $resolvedUri),
[
'code' => 404,
Expand All @@ -126,7 +129,7 @@ public function onCall(WAMPConnection $connection, string $id, string $resolvedU
} catch (WebSocketException $exception) {
$connection->callError(
$id,
'https://example.com/error#not-found', // TODO - Make the error URI customizable
$this->errorUriResolver->resolve('not-found'),
sprintf('Could not find a message handler for URI "%s".', $resolvedUri),
[
'code' => 404,
Expand Down
30 changes: 30 additions & 0 deletions tests/WAMP/DefaultErrorUriResolverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php declare(strict_types=1);

namespace BabDev\WebSocket\Server\Tests\WAMP;

use BabDev\WebSocket\Server\WAMP\DefaultErrorUriResolver;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class DefaultErrorUriResolverTest extends TestCase
{
/**
* @return \Generator<string, array{non-empty-string, non-empty-string}>
*/
public static function dataSupportedErrors(): \Generator
{
yield '"not-found" error' => ['not-found', 'https://example.com/error#not-found'];

yield 'Unknown error' => ['unknown', 'https://example.com/error#generic'];
}

/**
* @param non-empty-string $errorType
* @param non-empty-string $expected
*/
#[DataProvider('dataSupportedErrors')]
public function testResolve(string $errorType, string $expected): void
{
$this->assertSame($expected, (new DefaultErrorUriResolver())->resolve($errorType));
}
}

0 comments on commit 6591f2c

Please sign in to comment.