Skip to content

fix(youtube): stop swallowing channel-list errors in pages() - #2070

Open
giladresisi wants to merge 1 commit into
stagingfrom
fix/youtube-pages-surface-errors
Open

giladresisi wants to merge 1 commit into
stagingfrom
fix/youtube-pages-surface-errors

Conversation

@giladresisi

Copy link
Copy Markdown
Collaborator

What kind of change does this PR introduce?

Observability fix (backend, YouTube provider). YoutubeProvider.pages() wrapped channels.list in a try/catch that logged to the console and returned an empty list. The try/catch is removed so the error propagates from the pages function endpoint and is captured by the Nest Sentry integration, matching FacebookProvider.pages(), which has no catch. The channel mapping and the mine: true query are unchanged. The frontend continue-integration dialog already catches a failed request in its loadData and renders the same "We couldn't find any YouTube channels" empty state, so the customer-facing behavior is identical.

Why was this change needed?

A customer with several YouTube channels under one Google account connected one channel, then had two more attempts stay stuck at the channel-selection step. The second attempt reused the personal account and only re-offered the already-connected channel. The third attempt was a brand account and never got past selection. Its failure is unexplained: with the catch in place, a failed channel listing leaves nothing in Sentry or the DB, only a console line, so it cannot be distinguished from the user closing the dialog. Letting the throw propagate gives us the actual API error next time.

The alternative, keeping the catch and calling Sentry.captureException inside it, was not chosen: no provider calls Sentry directly today (the only direct use is a metrics counter in the posts service), so it would introduce a new pattern for the same result.

Other information:

The "already connected channel offered again" case shows a heading with an empty grid in the shared continue dialog. That is a separate UX issue that overlaps with PR #1719 and is not addressed here.

QA

  1. Start adding a YouTube channel and complete the Google consent screen so the "Configure Channel" dialog opens.
  2. With a valid token, the channel tile still appears and can be saved.
  3. Temporarily break the listing (for example revoke the app at myaccount.google.com/permissions before the dialog loads, or point channels.list at an invalid part) and reopen the dialog.
  4. The dialog shows "We couldn't find any YouTube channels connected to your account" as before.
  5. The backend log and Sentry now carry the actual Google API error for the pages function call instead of only a console line.

Checklist:

  • I have read the CONTRIBUTING guide.
  • I have signed the Contributor License Agreement (CLA).
  • I confirm I have not used AI to submit this PR or generate code for it.
  • I checked that there were no similar issues or PRs already open for this.
  • This PR fixes just ONE issue
  • I have filled in the QA section above with real steps to verify this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_017gsRv3MWm5YFweP58FM31H

Let a failed channels.list propagate like the Facebook provider does, so
the error reaches Sentry instead of being turned into an empty list. The
continue-integration dialog already catches the failed request and shows
the same "no channels found" state.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gsRv3MWm5YFweP58FM31H
@postiz-contribution postiz-contribution Bot added the contribution:approved Approved contributor label Sep 11, 2026
@strix-security

strix-security Bot commented Sep 11, 2026

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for 47c66c7.


Reviewed by Strix
Re-run review · Configure security review settings

@postiz-agent

postiz-agent Bot commented Sep 11, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Comment on lines +352 to +362
return channels.map((channel) => ({
id: channel.id!,
name: channel.snippet?.title || 'Unnamed Channel',
picture: {
data: {
url: channel.snippet?.thumbnails?.default?.url || '',
},
username: channel.snippet?.customUrl || '',
subscriberCount: channel.statistics?.subscriberCount || '0',
}));
} catch (error) {
console.error('Failed to fetch YouTube channels:', error);
return [];
}
},
username: channel.snippet?.customUrl || '',
subscriberCount: channel.statistics?.subscriberCount || '0',
}));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Removing the try/catch in pages() causes an unhandled exception in the reConnect() path during token refresh, as the calling refreshProcess() does not handle errors from reConnect().
Severity: MEDIUM

Suggested Fix

Wrap the call to integrationProvider.reConnect() within the refreshProcess() function in refresh.integration.service.ts with a try/catch block. This will handle potential failures from the pages() method during the token refresh workflow gracefully, preventing the process from crashing while allowing for proper error logging.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location:
libraries/nestjs-libraries/src/integrations/social/youtube.provider.ts#L341-L362

Potential issue: The removal of the `try/catch` block within the `pages()` method
introduces an unhandled exception in the token refresh workflow. While the primary
`connectSocialMedia` flow remains unaffected due to an existing controller-level
`try/catch`, the `reConnect()` method calls `pages()` without any error handling. The
caller, `refreshProcess()`, also lacks a `try/catch` around the `reConnect()` call.
Consequently, any API error from `youtubeClient.channels.list()` during a token refresh
will now cause the refresh workflow to crash, whereas it previously failed silently by
returning an empty array.

Also affects:

  • apps/backend/src/api/routes/no.auth.integrations.controller.ts:265~285

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a behavior change. Before this PR a failed channels.list made pages() return [], so reConnect() threw "Channel not found" at the same point in refreshProcess(). The refresh path already handled a throw there; it now gets the real Google error instead of a misleading one. The no-auth controller call site already has its own try/catch around pages().

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution:approved Approved contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant