fix(social): publish retry honors PlatformUnavailable too
Edge case from the prior commits: if the publisher throws TokenExpired (401 path), PublishToSocialPlatform attempts refreshAccountToken() to recover. That internally goes through ConnectionVerifier::verify, which can now raise PlatformUnavailable (5xx). The old catch (\Throwable) swallowed it but the loop still fell through to markAsTokenExpired — meaning a transient platform outage during a retry could still flip the account to expired. Adds an explicit PlatformUnavailable catch in the retry block: marks the post failed with category platform_unavailable and breaks before touching the account status.
This commit is contained in:
parent
04975020e4
commit
a42962c0ca
2 changed files with 43 additions and 0 deletions
|
|
@ -130,6 +130,19 @@ public function handle(): void
|
|||
$this->refreshAccountToken();
|
||||
|
||||
continue;
|
||||
} catch (PlatformUnavailableException $refreshError) {
|
||||
Log::warning('Publish skipped: platform unavailable during retry refresh', [
|
||||
'post_platform_id' => $this->postPlatform->id,
|
||||
'platform' => $this->postPlatform->platform->value,
|
||||
'error' => $refreshError->getMessage(),
|
||||
]);
|
||||
|
||||
$this->postPlatform->markAsFailed($refreshError->getMessage(), [
|
||||
'category' => 'platform_unavailable',
|
||||
'http_status' => $refreshError->httpStatus,
|
||||
'failed_at' => now()->toIso8601String(),
|
||||
]);
|
||||
break;
|
||||
} catch (\Throwable $refreshError) {
|
||||
Log::error('Token refresh failed during publish retry', [
|
||||
'post_platform_id' => $this->postPlatform->id,
|
||||
|
|
|
|||
|
|
@ -110,6 +110,36 @@
|
|||
expect($this->socialAccount->status)->toBe(AccountStatus::TokenExpired);
|
||||
});
|
||||
|
||||
test('publish does NOT mark account expired when retry refresh hits platform unavailable', function () {
|
||||
Event::fake();
|
||||
Mail::fake();
|
||||
|
||||
// Publisher first throws TokenExpired (401-style), the retry-refresh
|
||||
// path goes through ConnectionVerifier::verify which can in turn raise
|
||||
// PlatformUnavailable if the platform is down. The account must stay
|
||||
// Connected — it was the platform that failed, not the token.
|
||||
$publisher = Mockery::mock(LinkedInPublisher::class);
|
||||
$publisher->shouldReceive('publish')->andThrow(new TokenExpiredException('Token expired', '401'));
|
||||
|
||||
$verifier = Mockery::mock(ConnectionVerifier::class);
|
||||
$verifier->shouldReceive('verify')->andThrow(
|
||||
new PlatformUnavailableException('LinkedIn API returned 503 during token refresh', 503)
|
||||
);
|
||||
|
||||
$this->app->instance(LinkedInPublisher::class, $publisher);
|
||||
$this->app->instance(ConnectionVerifier::class, $verifier);
|
||||
|
||||
(new PublishToSocialPlatform($this->postPlatform))->handle();
|
||||
|
||||
$this->postPlatform->refresh();
|
||||
$this->socialAccount->refresh();
|
||||
|
||||
expect($this->postPlatform->status)->toBe(PlatformStatus::Failed);
|
||||
expect($this->postPlatform->error_context['category'] ?? null)->toBe('platform_unavailable');
|
||||
expect($this->postPlatform->error_context['http_status'] ?? null)->toBe(503);
|
||||
expect($this->socialAccount->status)->toBe(AccountStatus::Connected);
|
||||
});
|
||||
|
||||
test('publish to social platform does NOT mark account expired when platform is unavailable', function () {
|
||||
Event::fake();
|
||||
Mail::fake();
|
||||
|
|
|
|||
Loading…
Reference in a new issue