1
0
mirror of https://github.com/flarum/core.git synced 2025-08-06 08:27:42 +02:00

fix: handled API errors break preloaded content (#3920)

* fix: handled API errors break preloaded content

* Apply fixes from StyleCI

---------

Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
Sami Mazouz
2023-11-10 22:39:08 +01:00
committed by GitHub
parent deb99f0de4
commit 5e3f8db095
9 changed files with 147 additions and 37 deletions

View File

@@ -96,8 +96,15 @@ class Tag
protected function getTagsDocument(Request $request, string $slug): object protected function getTagsDocument(Request $request, string $slug): object
{ {
return json_decode($this->api->withParentRequest($request)->withQueryParams([ return json_decode(
'include' => 'children,children.parent,parent,parent.children.parent,state' $this->api
])->get("/tags/$slug")->getBody()); ->withoutErrorHandling()
->withParentRequest($request)
->withQueryParams([
'include' => 'children,children.parent,parent,parent.children.parent,state'
])
->get("/tags/$slug")
->getBody()
);
} }
} }

View File

@@ -58,8 +58,16 @@ class Tags
protected function getTagsDocument(Request $request): array protected function getTagsDocument(Request $request): array
{ {
return json_decode($this->api->withParentRequest($request)->withQueryParams([ return json_decode(
'include' => 'children,lastPostedDiscussion,parent' $this->api
])->get('/tags')->getBody(), true); ->withoutErrorHandling()
->withParentRequest($request)
->withQueryParams([
'include' => 'children,lastPostedDiscussion,parent'
])
->get('/tags')
->getBody(),
true
);
} }
} }

View File

@@ -114,21 +114,17 @@ class ApiServiceProvider extends AbstractServiceProvider
}); });
$this->container->singleton(Client::class, function ($container) { $this->container->singleton(Client::class, function ($container) {
$pipe = new MiddlewarePipe;
$exclude = $container->make('flarum.api_client.exclude_middleware'); $exclude = $container->make('flarum.api_client.exclude_middleware');
$middlewareStack = array_filter($container->make('flarum.api.middleware'), function ($middlewareClass) use ($exclude) { $middlewareStack = array_filter($container->make('flarum.api.middleware'), function ($middlewareClass) use ($exclude) {
return ! in_array($middlewareClass, $exclude); return ! in_array($middlewareClass, $exclude);
}); });
foreach ($middlewareStack as $middleware) { $middlewareStack[] = HttpMiddleware\ExecuteRoute::class;
$pipe->pipe($container->make($middleware));
}
$pipe->pipe(new HttpMiddleware\ExecuteRoute()); return new Client(
new ClientMiddlewarePipe($container, $middlewareStack)
return new Client($pipe); );
}); });
} }

View File

@@ -13,7 +13,6 @@ use Flarum\Http\RequestUtil;
use Flarum\User\User; use Flarum\User\User;
use Laminas\Diactoros\ServerRequestFactory; use Laminas\Diactoros\ServerRequestFactory;
use Laminas\Diactoros\Uri; use Laminas\Diactoros\Uri;
use Laminas\Stratigility\MiddlewarePipeInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@@ -23,9 +22,10 @@ class Client
protected ?ServerRequestInterface $parent = null; protected ?ServerRequestInterface $parent = null;
protected array $queryParams = []; protected array $queryParams = [];
protected array $body = []; protected array $body = [];
protected bool $errorHandling = true;
public function __construct( public function __construct(
protected MiddlewarePipeInterface $pipe protected ClientMiddlewarePipe $pipe
) { ) {
} }
@@ -66,6 +66,22 @@ class Client
return $new; 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 public function get(string $path): ResponseInterface
{ {
return $this->send('GET', $path); return $this->send('GET', $path);
@@ -114,6 +130,8 @@ class Client
$request = RequestUtil::withActor($request, $this->actor); $request = RequestUtil::withActor($request, $this->actor);
} }
return $this->pipe->handle($request); return $this->pipe
->errorHandling($this->errorHandling)
->handle($request);
} }
} }

View File

@@ -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;
}
}

View File

@@ -95,16 +95,14 @@ class Discussion
protected function getApiDocument(Request $request, string $id, array $params): object protected function getApiDocument(Request $request, string $id, array $params): object
{ {
$params['bySlug'] = true; $params['bySlug'] = true;
$response = $this->api
->withParentRequest($request)
->withQueryParams($params)
->get("/discussions/$id");
$statusCode = $response->getStatusCode();
if ($statusCode === 404) { return json_decode(
throw new RouteNotFoundException; $this->api
} ->withoutErrorHandling()
->withParentRequest($request)
return json_decode($response->getBody()); ->withQueryParams($params)
->get("/discussions/$id")
->getBody()
);
} }
} }

View File

@@ -75,6 +75,13 @@ class Index
*/ */
protected function getApiDocument(Request $request, array $params): object 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()
);
} }
} }

View File

@@ -46,13 +46,12 @@ class User
*/ */
protected function getApiDocument(Request $request, string $username): object protected function getApiDocument(Request $request, string $username): object
{ {
$response = $this->api->withParentRequest($request)->withQueryParams(['bySlug' => true])->get("/users/$username"); return json_decode(
$statusCode = $response->getStatusCode(); $this->api
->withoutErrorHandling()
if ($statusCode === 404) { ->withParentRequest($request)
throw new ModelNotFoundException; ->withQueryParams(['bySlug' => true])
} ->get("/users/$username")->getBody()
);
return json_decode($response->getBody());
} }
} }

View File

@@ -59,7 +59,9 @@ class Frontend
private function getForumDocument(Request $request): array private function getForumDocument(Request $request): array
{ {
return $this->getResponseBody( return $this->getResponseBody(
$this->api->withParentRequest($request)->get('/') $this->api->withoutErrorHandling()
->withParentRequest($request)
->get('/')
); );
} }