diff --git a/src/Contact/Avatar.php b/src/Contact/Avatar.php index e039a5279..299c26399 100644 --- a/src/Contact/Avatar.php +++ b/src/Contact/Avatar.php @@ -73,7 +73,12 @@ class Avatar return $fields; } - $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); + try { + $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); + } catch (\Exception $exception) { + Logger::notice('Avatar is invalid', ['avatar' => $avatar, 'exception' => $exception]); + return $fields; + } $img_str = $fetchResult->getBody(); if (empty($img_str)) { diff --git a/src/Core/Storage/Repository/StorageManager.php b/src/Core/Storage/Repository/StorageManager.php index fbe910d01..252454665 100644 --- a/src/Core/Storage/Repository/StorageManager.php +++ b/src/Core/Storage/Repository/StorageManager.php @@ -168,7 +168,7 @@ class StorageManager return $data['storage_config']; } catch (InternalServerErrorException $exception) { - throw new StorageException(sprintf('Failed calling hook::storage_config for backend %s', $name), $exception); + throw new StorageException(sprintf('Failed calling hook::storage_config for backend %s', $name), $exception->__toString()); } } } @@ -208,7 +208,7 @@ class StorageManager $this->backendInstances[$name] = new Type\SystemResource(); break; case Type\ExternalResource::getName(): - $this->backendInstances[$name] = new Type\ExternalResource(); + $this->backendInstances[$name] = new Type\ExternalResource($this->logger); break; default: $data = [ @@ -223,7 +223,7 @@ class StorageManager $this->backendInstances[$data['name'] ?? $name] = $data['storage']; } catch (InternalServerErrorException $exception) { - throw new StorageException(sprintf('Failed calling hook::storage_instance for backend %s', $name), $exception); + throw new StorageException(sprintf('Failed calling hook::storage_instance for backend %s', $name), $exception->__toString()); } break; } diff --git a/src/Core/Storage/Type/ExternalResource.php b/src/Core/Storage/Type/ExternalResource.php index 055db0dea..181312a5b 100644 --- a/src/Core/Storage/Type/ExternalResource.php +++ b/src/Core/Storage/Type/ExternalResource.php @@ -22,12 +22,12 @@ namespace Friendica\Core\Storage\Type; use Exception; -use Friendica\Core\Logger; use Friendica\Core\Storage\Exception\ReferenceStorageException; use Friendica\Core\Storage\Capability\ICanReadFromStorage; use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Util\HTTPSignature; +use Psr\Log\LoggerInterface; /** * External resource storage class @@ -39,6 +39,14 @@ class ExternalResource implements ICanReadFromStorage { const NAME = 'ExternalResource'; + /** @var LoggerInterface */ + protected $logger; + + public function __construct(LoggerInterface $logger) + { + $this->logger = $logger; + } + /** * @inheritDoc */ @@ -57,10 +65,11 @@ class ExternalResource implements ICanReadFromStorage try { $fetchResult = HTTPSignature::fetchRaw($data->url, $data->uid, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); } catch (Exception $exception) { + $this->logger->notice('URL is invalid', ['url' => $data->url, 'error' => $exception]); throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $exception->getCode(), $exception); } if (!empty($fetchResult) && $fetchResult->isSuccess()) { - Logger::debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]); + $this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]); return $fetchResult->getBody(); } else { if (empty($fetchResult)) { diff --git a/src/Factory/Api/Mastodon/Notification.php b/src/Factory/Api/Mastodon/Notification.php index 52241e1fc..e6e9f4d09 100644 --- a/src/Factory/Api/Mastodon/Notification.php +++ b/src/Factory/Api/Mastodon/Notification.php @@ -64,7 +64,7 @@ class Notification extends BaseFactory if ($Notification->targetUriId) { try { $status = $this->mstdnStatusFactory->createFromUriId($Notification->targetUriId, $Notification->uid, $display_quotes); - } catch (\Throwable $th) { + } catch (\Exception $exception) { $status = null; } } else { diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index fed7ea473..19f3866cd 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -269,8 +269,8 @@ class Status extends BaseFactory if ($is_reshare) { try { $reshare = $this->createFromUriId($uriId, $uid, $display_quote, false, false)->toArray(); - } catch (\Throwable $th) { - Logger::info('Reshare not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Reshare not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); $reshare = []; } } else { @@ -280,8 +280,8 @@ class Status extends BaseFactory if ($in_reply_status && ($item['gravity'] == Item::GRAVITY_COMMENT)) { try { $in_reply = $this->createFromUriId($item['thr-parent-id'], $uid, $display_quote, false, false)->toArray(); - } catch (\Throwable $th) { - Logger::info('Reply post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Reply post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); $in_reply = []; } } else { @@ -315,8 +315,8 @@ class Status extends BaseFactory if (!empty($quote_id)) { try { $quote = $this->createFromUriId($quote_id, $uid, false, false, false)->toArray(); - } catch (\Throwable $th) { - Logger::info('Quote not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Quote not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); $quote = []; } } else { diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 215d7e317..20457b46e 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -189,17 +189,22 @@ class APContact if (empty($data)) { $local_owner = []; - $curlResult = HTTPSignature::fetchRaw($url); - $failed = empty($curlResult) || empty($curlResult->getBody()) || - (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410)); + try { + $curlResult = HTTPSignature::fetchRaw($url); + $failed = empty($curlResult) || empty($curlResult->getBody()) || + (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410)); + + if (!$failed) { + $data = json_decode($curlResult->getBody(), true); + $failed = empty($data) || !is_array($data); + } - if (!$failed) { - $data = json_decode($curlResult->getBody(), true); - $failed = empty($data) || !is_array($data); - } - - if (!$failed && ($curlResult->getReturnCode() == 410)) { - $data = ['@context' => ActivityPub::CONTEXT, 'id' => $url, 'type' => 'Tombstone']; + if (!$failed && ($curlResult->getReturnCode() == 410)) { + $data = ['@context' => ActivityPub::CONTEXT, 'id' => $url, 'type' => 'Tombstone']; + } + } catch (\Exception $exception) { + Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]); + $failed = true; } if ($failed) { diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 571253f42..f35808f05 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2216,16 +2216,21 @@ class Contact if (($contact['avatar'] != $avatar) || empty($contact['blurhash'])) { $update_fields = ['avatar' => $avatar]; if (!Network::isLocalLink($avatar)) { - $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); + try { + $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); - $img_str = $fetchResult->getBody(); - if (!empty($img_str)) { - $image = new Image($img_str, Images::getMimeTypeByData($img_str)); - if ($image->isValid()) { - $update_fields['blurhash'] = $image->getBlurHash(); - } else { - return; + $img_str = $fetchResult->getBody(); + if (!empty($img_str)) { + $image = new Image($img_str, Images::getMimeTypeByData($img_str)); + if ($image->isValid()) { + $update_fields['blurhash'] = $image->getBlurHash(); + } else { + return; + } } + } catch (\Exception $exception) { + Logger::notice('Error fetching avatar', ['avatar' => $avatar, 'exception' => $exception]); + return; } } elseif (!empty($contact['blurhash'])) { $update_fields['blurhash'] = null; diff --git a/src/Model/Post/Link.php b/src/Model/Post/Link.php index 343ad815c..dc7797951 100644 --- a/src/Model/Post/Link.php +++ b/src/Model/Post/Link.php @@ -125,8 +125,13 @@ class Link { $timeout = DI::config()->get('system', 'xrd_timeout'); - $curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]); - if (empty($curlResult) || !$curlResult->isSuccess()) { + try { + $curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]); + if (empty($curlResult) || !$curlResult->isSuccess()) { + return []; + } + } catch (\Exception $exception) { + Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]); return []; } $fields = ['mimetype' => $curlResult->getHeader('Content-Type')[0]]; diff --git a/src/Module/Api/Mastodon/Accounts/Statuses.php b/src/Module/Api/Mastodon/Accounts/Statuses.php index 067e33027..463411745 100644 --- a/src/Module/Api/Mastodon/Accounts/Statuses.php +++ b/src/Module/Api/Mastodon/Accounts/Statuses.php @@ -120,8 +120,8 @@ class Statuses extends BaseApi self::setBoundaries($item['uri-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Bookmarks.php b/src/Module/Api/Mastodon/Bookmarks.php index 615bfc501..59cf7f54a 100644 --- a/src/Module/Api/Mastodon/Bookmarks.php +++ b/src/Module/Api/Mastodon/Bookmarks.php @@ -77,8 +77,8 @@ class Bookmarks extends BaseApi self::setBoundaries($item['uri-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Favourited.php b/src/Module/Api/Mastodon/Favourited.php index 93c9ef243..7829f37d7 100644 --- a/src/Module/Api/Mastodon/Favourited.php +++ b/src/Module/Api/Mastodon/Favourited.php @@ -79,8 +79,8 @@ class Favourited extends BaseApi self::setBoundaries($item['thr-parent-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['thr-parent-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['thr-parent-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['thr-parent-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Lists/Accounts.php b/src/Module/Api/Mastodon/Lists/Accounts.php index 667cd87ea..e19dfb031 100644 --- a/src/Module/Api/Mastodon/Lists/Accounts.php +++ b/src/Module/Api/Mastodon/Lists/Accounts.php @@ -117,7 +117,7 @@ class Accounts extends BaseApi self::setBoundaries($member['contact-id']); try { $accounts[] = DI::mstdnAccount()->createFromContactId($member['contact-id'], $uid); - } catch (\Throwable $th) { + } catch (\Exception $exception) { } } DBA::close($members); diff --git a/src/Module/Api/Mastodon/Search.php b/src/Module/Api/Mastodon/Search.php index c35e33062..69e262768 100644 --- a/src/Module/Api/Mastodon/Search.php +++ b/src/Module/Api/Mastodon/Search.php @@ -183,8 +183,8 @@ class Search extends BaseApi self::setBoundaries($item['uri-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Timelines/Home.php b/src/Module/Api/Mastodon/Timelines/Home.php index 5efaf4930..7fc179297 100644 --- a/src/Module/Api/Mastodon/Timelines/Home.php +++ b/src/Module/Api/Mastodon/Timelines/Home.php @@ -99,8 +99,8 @@ class Home extends BaseApi self::setBoundaries($item['uri-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Timelines/ListTimeline.php b/src/Module/Api/Mastodon/Timelines/ListTimeline.php index a8de13056..1e9a5810c 100644 --- a/src/Module/Api/Mastodon/Timelines/ListTimeline.php +++ b/src/Module/Api/Mastodon/Timelines/ListTimeline.php @@ -104,8 +104,8 @@ class ListTimeline extends BaseApi self::setBoundaries($item['uri-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php index 968e34dbb..31750d4a5 100644 --- a/src/Module/Api/Mastodon/Timelines/PublicTimeline.php +++ b/src/Module/Api/Mastodon/Timelines/PublicTimeline.php @@ -99,8 +99,8 @@ class PublicTimeline extends BaseApi self::setBoundaries($item['uri-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Timelines/Tag.php b/src/Module/Api/Mastodon/Timelines/Tag.php index 64cd84366..476c9c2b9 100644 --- a/src/Module/Api/Mastodon/Timelines/Tag.php +++ b/src/Module/Api/Mastodon/Timelines/Tag.php @@ -120,8 +120,8 @@ class Tag extends BaseApi self::setBoundaries($item['uri-id']); try { $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($items); diff --git a/src/Module/Api/Mastodon/Trends/Statuses.php b/src/Module/Api/Mastodon/Trends/Statuses.php index 884319aa4..336f67155 100644 --- a/src/Module/Api/Mastodon/Trends/Statuses.php +++ b/src/Module/Api/Mastodon/Trends/Statuses.php @@ -57,8 +57,8 @@ class Statuses extends BaseApi while ($status = Post::fetch($statuses)) { try { $trending[] = DI::mstdnStatus()->createFromUriId($status['uri-id'], $uid, $display_quotes); - } catch (\Throwable $th) { - Logger::info('Post not fetchable', ['uri-id' => $status['uri-id'], 'uid' => $uid, 'error' => $th]); + } catch (\Exception $exception) { + Logger::info('Post not fetchable', ['uri-id' => $status['uri-id'], 'uid' => $uid, 'exception' => $exception]); } } DBA::close($statuses); diff --git a/src/Module/Proxy.php b/src/Module/Proxy.php index ab129a82c..4d1e1c304 100644 --- a/src/Module/Proxy.php +++ b/src/Module/Proxy.php @@ -83,13 +83,18 @@ class Proxy extends BaseModule $request['url'] = str_replace(' ', '+', $request['url']); // Fetch the content with the local user - $fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]); - $img_str = $fetchResult->getBody(); + try { + $fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]); + $img_str = $fetchResult->getBody(); - if (!$fetchResult->isSuccess() || empty($img_str)) { - Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]); + if (!$fetchResult->isSuccess() || empty($img_str)) { + Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]); + self::responseError(); + // stop. + } + } catch (\Exception $exception) { + Logger::notice('Error fetching image', ['image' => $request['url'], 'exception' => $exception]); self::responseError(); - // stop. } Logger::debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => DI::userSession()->getLocalUserId(), 'image' => $request['url']]); diff --git a/src/Object/Image.php b/src/Object/Image.php index d6c897e88..49196a0c4 100644 --- a/src/Object/Image.php +++ b/src/Object/Image.php @@ -718,7 +718,7 @@ class Image if ($image->isImagick()) { try { $colors = $image->image->getImagePixelColor($x, $y)->getColor(); - } catch (\Throwable $th) { + } catch (\Exception $exception) { return ''; } $row[] = [$colors['r'], $colors['g'], $colors['b']]; diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 11267cfaf..54acca9df 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -570,7 +570,12 @@ class Processor */ public static function isActivityGone(string $url): bool { - $curlResult = HTTPSignature::fetchRaw($url, 0); + try { + $curlResult = HTTPSignature::fetchRaw($url, 0); + } catch (\Exception $exception) { + Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]); + return true; + } if (Network::isUrlBlocked($url)) { return true; diff --git a/src/Util/HTTPSignature.php b/src/Util/HTTPSignature.php index f082fe32f..d48d02c20 100644 --- a/src/Util/HTTPSignature.php +++ b/src/Util/HTTPSignature.php @@ -422,7 +422,12 @@ class HTTPSignature */ public static function fetch(string $request, int $uid): array { - $curlResult = self::fetchRaw($request, $uid); + try { + $curlResult = self::fetchRaw($request, $uid); + } catch (\Exception $exception) { + Logger::notice('Error fetching url', ['url' => $request, 'exception' => $exception]); + return []; + } if (empty($curlResult)) { return [];