Catch API timeouts
This commit is contained in:
parent
255895097a
commit
ea2b4fe148
@ -54,7 +54,9 @@ class JsonAPI {
|
||||
];
|
||||
|
||||
// Reorganize included data
|
||||
$included = static::organizeIncluded($data['included']);
|
||||
$included = (array_key_exists('included', $data))
|
||||
? static::organizeIncluded($data['included'])
|
||||
: [];
|
||||
|
||||
// Inline organized data
|
||||
foreach($data['data'] as $i => &$item)
|
||||
@ -138,10 +140,7 @@ class JsonAPI {
|
||||
continue;
|
||||
}
|
||||
|
||||
$relationship[$typeKey][$idKey] = array_merge(
|
||||
$included[$typeKey][$idKey],
|
||||
$relationship[$typeKey][$idKey] ?? []
|
||||
);
|
||||
$relationship[$typeKey][$idKey][$j] = $included[$typeKey][$idKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,6 +148,8 @@ class JsonAPI {
|
||||
}
|
||||
}
|
||||
|
||||
$data['data']['included'] = $included;
|
||||
|
||||
return $data['data'];
|
||||
}
|
||||
|
||||
@ -202,11 +203,11 @@ class JsonAPI {
|
||||
{
|
||||
foreach($items as $id => $item)
|
||||
{
|
||||
if (array_key_exists('relationships', $item))
|
||||
if (array_key_exists('relationships', $item) && is_array($item['relationships']))
|
||||
{
|
||||
foreach($item['relationships'] as $relType => $props)
|
||||
{
|
||||
if (array_key_exists('data', $props))
|
||||
if (array_key_exists('data', $props) && is_array($props['data']) && array_key_exists('id', $props['data']))
|
||||
{
|
||||
if (array_key_exists($props['data']['id'], $organized[$props['data']['type']]))
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ use function Amp\wait;
|
||||
|
||||
use Amp\Artax\{Client, Request};
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
use Aviat\AnimeClient\API\Kitsu as K;
|
||||
use Aviat\AnimeClient\API\{FailedResponseException, Kitsu as K};
|
||||
use Aviat\Ion\Json;
|
||||
|
||||
trait KitsuTrait {
|
||||
@ -142,8 +142,10 @@ trait KitsuTrait {
|
||||
{
|
||||
if ($logger)
|
||||
{
|
||||
$logger->warning('Non 200 response for api call', (array)$response->getBody());
|
||||
$logger->warning('Non 200 response for api call', (array)$response);
|
||||
}
|
||||
|
||||
throw new FailedResponseException('Failed to get the proper response from the API');
|
||||
}
|
||||
|
||||
return Json::decode($response->getBody(), TRUE);
|
||||
|
@ -160,13 +160,16 @@ class Model {
|
||||
*/
|
||||
public function getCharacter(string $slug): array
|
||||
{
|
||||
// @todo catch non-existent characters and show 404
|
||||
$data = $this->getRequest('/characters', [
|
||||
'query' => [
|
||||
'filter' => [
|
||||
'name' => $slug
|
||||
'slug' => $slug,
|
||||
],
|
||||
// 'include' => 'primaryMedia,castings'
|
||||
'fields' => [
|
||||
'anime' => 'canonicalTitle,titles,slug,posterImage',
|
||||
'manga' => 'canonicalTitle,titles,slug,posterImage'
|
||||
],
|
||||
'include' => 'castings.person,castings.media'
|
||||
]
|
||||
]);
|
||||
|
||||
|
@ -17,19 +17,23 @@
|
||||
namespace Aviat\AnimeClient\Controller;
|
||||
|
||||
use Aviat\AnimeClient\Controller as BaseController;
|
||||
use Aviat\AnimeClient\API\JsonAPI;
|
||||
use Aviat\Ion\ArrayWrapper;
|
||||
|
||||
/**
|
||||
* Controller for character description pages
|
||||
*/
|
||||
class Character extends BaseController {
|
||||
|
||||
use ArrayWrapper;
|
||||
|
||||
public function index(string $slug)
|
||||
{
|
||||
$model = $this->container->get('kitsu-model');
|
||||
|
||||
$data = $model->getCharacter($slug);
|
||||
$rawData = $model->getCharacter($slug);
|
||||
|
||||
if (( ! array_key_exists('data', $data)) || empty($data['data']))
|
||||
if (( ! array_key_exists('data', $rawData)) || empty($rawData['data']))
|
||||
{
|
||||
return $this->notFound(
|
||||
$this->formatTitle(
|
||||
@ -40,12 +44,98 @@ class Character extends BaseController {
|
||||
);
|
||||
}
|
||||
|
||||
$this->outputHTML('character', [
|
||||
$data = JsonAPI::organizeData($rawData);
|
||||
|
||||
$viewData = [
|
||||
'title' => $this->formatTitle(
|
||||
'Characters',
|
||||
$data['data'][0]['attributes']['name']
|
||||
$data[0]['attributes']['name']
|
||||
),
|
||||
'data' => $data['data'][0]['attributes']
|
||||
]);
|
||||
'data' => $data,
|
||||
'castings' => []
|
||||
];
|
||||
|
||||
if (array_key_exists('included', $data) && array_key_exists('castings', $data['included']))
|
||||
{
|
||||
$viewData['castings'] = $this->organizeCast($data['included']['castings']);
|
||||
}
|
||||
|
||||
$this->outputHTML('character', $viewData);
|
||||
}
|
||||
|
||||
private function dedupeCast(array $cast): array
|
||||
{
|
||||
$output = [];
|
||||
$people = [];
|
||||
|
||||
$i = 0;
|
||||
foreach ($cast as &$role)
|
||||
{
|
||||
if (empty($role['attributes']['role']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$person = current($role['relationships']['person']['people'])['attributes'];
|
||||
|
||||
if ( ! array_key_exists($person['name'], $people))
|
||||
{
|
||||
$people[$person['name']] = $i;
|
||||
$role['relationships']['media']['anime'] = [current($role['relationships']['media']['anime'])];
|
||||
$output[$i] = $role;
|
||||
|
||||
$i++;
|
||||
|
||||
continue;
|
||||
}
|
||||
else if(array_key_exists($person['name'], $people))
|
||||
{
|
||||
if (array_key_exists('anime', $role['relationships']['media']))
|
||||
{
|
||||
$key = $people[$person['name']];
|
||||
$output[$key]['relationships']['media']['anime'][] = current($role['relationships']['media']['anime']);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function organizeCast(array $cast): array
|
||||
{
|
||||
$cast = $this->dedupeCast($cast);
|
||||
$output = [];
|
||||
|
||||
foreach($cast as $id => $role)
|
||||
{
|
||||
if (empty($role['attributes']['role']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$language = $role['attributes']['language'];
|
||||
$roleName = $role['attributes']['role'];
|
||||
$isVA = $role['attributes']['voiceActor'];
|
||||
|
||||
if ($isVA)
|
||||
{
|
||||
$person = current($role['relationships']['person']['people'])['attributes'];
|
||||
$name = $person['name'];
|
||||
$item = [
|
||||
'person' => $person,
|
||||
'series' => $role['relationships']['media']['anime']
|
||||
];
|
||||
|
||||
$output[$roleName][$language][] = $item;
|
||||
}
|
||||
else
|
||||
{
|
||||
$output[$roleName][] = $role['relationships']['person']['people'];
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ use const Aviat\AnimeClient\{
|
||||
|
||||
use function Aviat\Ion\_dir;
|
||||
|
||||
use Aviat\AnimeClient\API\FailedResponseException;
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\Friend;
|
||||
|
||||
@ -256,14 +257,25 @@ class Dispatcher extends RoutingBase {
|
||||
{
|
||||
$logger = $this->container->getLogger('default');
|
||||
|
||||
try
|
||||
{
|
||||
$controller = new $controllerName($this->container);
|
||||
|
||||
// Run the appropriate controller method
|
||||
$logger->debug('Dispatcher - controller arguments');
|
||||
$logger->debug(print_r($params, TRUE));
|
||||
$logger->debug('Dispatcher - controller arguments', $params);
|
||||
|
||||
call_user_func_array([$controller, $method], $params);
|
||||
}
|
||||
catch (FailedResponseException $e)
|
||||
{
|
||||
$controllerName = DEFAULT_CONTROLLER;
|
||||
$controller = new $controllerName($this->container);
|
||||
$controller->errorPage(500,
|
||||
'API request timed out',
|
||||
'Failed to retrieve data from API ☹️');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate params for the error page
|
||||
|
Loading…
Reference in New Issue
Block a user