Skip to content

Commit

Permalink
fix: handled API errors break preloaded content (#3920)
Browse files Browse the repository at this point in the history
* fix: handled API errors break preloaded content

* Apply fixes from StyleCI

---------

Co-authored-by: StyleCI Bot <[email protected]>
  • Loading branch information
SychO9 and StyleCIBot authored Nov 10, 2023
1 parent deb99f0 commit 5e3f8db
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 37 deletions.
13 changes: 10 additions & 3 deletions extensions/tags/src/Content/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,15 @@ protected function getApiDocument(Request $request, array $params): object

protected function getTagsDocument(Request $request, string $slug): object
{
return json_decode($this->api->withParentRequest($request)->withQueryParams([
'include' => 'children,children.parent,parent,parent.children.parent,state'
])->get("/tags/$slug")->getBody());
return json_decode(
$this->api
->withoutErrorHandling()
->withParentRequest($request)
->withQueryParams([
'include' => 'children,children.parent,parent,parent.children.parent,state'
])
->get("/tags/$slug")
->getBody()
);
}
}
14 changes: 11 additions & 3 deletions extensions/tags/src/Content/Tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,16 @@ public function __invoke(Document $document, Request $request): Document

protected function getTagsDocument(Request $request): array
{
return json_decode($this->api->withParentRequest($request)->withQueryParams([
'include' => 'children,lastPostedDiscussion,parent'
])->get('/tags')->getBody(), true);
return json_decode(
$this->api
->withoutErrorHandling()
->withParentRequest($request)
->withQueryParams([
'include' => 'children,lastPostedDiscussion,parent'
])
->get('/tags')
->getBody(),
true
);
}
}
12 changes: 4 additions & 8 deletions framework/core/src/Api/ApiServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,17 @@ public function register(): void
});

$this->container->singleton(Client::class, function ($container) {
$pipe = new MiddlewarePipe;

$exclude = $container->make('flarum.api_client.exclude_middleware');

$middlewareStack = array_filter($container->make('flarum.api.middleware'), function ($middlewareClass) use ($exclude) {
return ! in_array($middlewareClass, $exclude);
});

foreach ($middlewareStack as $middleware) {
$pipe->pipe($container->make($middleware));
}
$middlewareStack[] = HttpMiddleware\ExecuteRoute::class;

$pipe->pipe(new HttpMiddleware\ExecuteRoute());

return new Client($pipe);
return new Client(
new ClientMiddlewarePipe($container, $middlewareStack)
);
});
}

Expand Down
24 changes: 21 additions & 3 deletions framework/core/src/Api/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Flarum\User\User;
use Laminas\Diactoros\ServerRequestFactory;
use Laminas\Diactoros\Uri;
use Laminas\Stratigility\MiddlewarePipeInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

Expand All @@ -23,9 +22,10 @@ class Client
protected ?ServerRequestInterface $parent = null;
protected array $queryParams = [];
protected array $body = [];
protected bool $errorHandling = true;

public function __construct(
protected MiddlewarePipeInterface $pipe
protected ClientMiddlewarePipe $pipe
) {
}

Expand Down Expand Up @@ -66,6 +66,22 @@ public function withBody(array $body): Client
return $new;
}

public function withoutErrorHandling(): Client
{
$new = clone $this;
$new->errorHandling = false;

return $new;
}

public function withErrorHandling(): Client
{
$new = clone $this;
$new->errorHandling = true;

return $new;
}

public function get(string $path): ResponseInterface
{
return $this->send('GET', $path);
Expand Down Expand Up @@ -114,6 +130,8 @@ public function send(string $method, string $path): ResponseInterface
$request = RequestUtil::withActor($request, $this->actor);
}

return $this->pipe->handle($request);
return $this->pipe
->errorHandling($this->errorHandling)
->handle($request);
}
}
75 changes: 75 additions & 0 deletions framework/core/src/Api/ClientMiddlewarePipe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/

namespace Flarum\Api;

use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Laminas\Stratigility\MiddlewarePipe;
use Laminas\Stratigility\MiddlewarePipeInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class ClientMiddlewarePipe implements MiddlewarePipeInterface
{
protected Collection $middlewares;
protected MiddlewarePipeInterface $pipe;

public function __construct(
protected Container $container,
array $middlewares
) {
$this->middlewares = new Collection($middlewares);
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
return $this->getPipe()->process($request, $handler);
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->getPipe()->handle($request);
}

public function pipe(MiddlewareInterface $middleware): void
{
$this->middlewares->push($middleware);
}

protected function getPipe(): MiddlewarePipeInterface
{
if (isset($this->pipe)) {
return $this->pipe;
}

$this->pipe = new MiddlewarePipe();

foreach ($this->middlewares as $middleware) {
$this->pipe->pipe($this->container->make($middleware));
}

return $this->pipe;
}

public function errorHandling(bool $handleErrors): static
{
$errorHandler = 'flarum.api.error_handler';

if ($handleErrors && ! $this->middlewares->contains($errorHandler)) {
$this->middlewares = $this->middlewares->prepend($errorHandler);
} elseif (! $handleErrors && $this->middlewares->contains($errorHandler)) {
$this->middlewares = $this->middlewares->reject($errorHandler);
}

return $this;
}
}
18 changes: 8 additions & 10 deletions framework/core/src/Forum/Content/Discussion.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,14 @@ public function __invoke(Document $document, Request $request): Document
protected function getApiDocument(Request $request, string $id, array $params): object
{
$params['bySlug'] = true;
$response = $this->api
->withParentRequest($request)
->withQueryParams($params)
->get("/discussions/$id");
$statusCode = $response->getStatusCode();

if ($statusCode === 404) {
throw new RouteNotFoundException;
}

return json_decode($response->getBody());
return json_decode(
$this->api
->withoutErrorHandling()
->withParentRequest($request)
->withQueryParams($params)
->get("/discussions/$id")
->getBody()
);
}
}
9 changes: 8 additions & 1 deletion framework/core/src/Forum/Content/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ public function __invoke(Document $document, Request $request): Document
*/
protected function getApiDocument(Request $request, array $params): object
{
return json_decode($this->api->withParentRequest($request)->withQueryParams($params)->get('/discussions')->getBody());
return json_decode(
$this->api
->withoutErrorHandling()
->withParentRequest($request)
->withQueryParams($params)
->get('/discussions')
->getBody()
);
}
}
15 changes: 7 additions & 8 deletions framework/core/src/Forum/Content/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,12 @@ public function __invoke(Document $document, Request $request): Document
*/
protected function getApiDocument(Request $request, string $username): object
{
$response = $this->api->withParentRequest($request)->withQueryParams(['bySlug' => true])->get("/users/$username");
$statusCode = $response->getStatusCode();

if ($statusCode === 404) {
throw new ModelNotFoundException;
}

return json_decode($response->getBody());
return json_decode(
$this->api
->withoutErrorHandling()
->withParentRequest($request)
->withQueryParams(['bySlug' => true])
->get("/users/$username")->getBody()
);
}
}
4 changes: 3 additions & 1 deletion framework/core/src/Frontend/Frontend.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ protected function populate(Document $document, Request $request): void
private function getForumDocument(Request $request): array
{
return $this->getResponseBody(
$this->api->withParentRequest($request)->get('/')
$this->api->withoutErrorHandling()
->withParentRequest($request)
->get('/')
);
}

Expand Down

0 comments on commit 5e3f8db

Please sign in to comment.