Skip to content

fix: prevent fatal errors when LinkedIn authorization fails - #1100

Open
lucadobrescu wants to merge 3 commits into
developmentfrom
fix/1098-linkedin-auth-error-handling
Open

fix: prevent fatal errors when LinkedIn authorization fails#1100
lucadobrescu wants to merge 3 commits into
developmentfrom
fix/1098-linkedin-auth-error-handling

Conversation

@lucadobrescu

@lucadobrescu lucadobrescu commented Jul 28, 2026

Copy link
Copy Markdown

When LinkedIn authorization fails during account connection, the plugin crashed to the WordPress critical-error screen instead of showing the LinkedIn error (issue #1098). The error-handling paths themselves fataled; this PR makes them report the failure and keep the dashboard alive.

What changed

  • Rop_Linkedin_Service::authorize() — the catch block called Exception::getDescription(), which does not exist on plain exceptions, so any caught error (e.g. a failed token exchange) became a second fatal. It now falls back to getMessage() and no longer assumes HTTP_REFERER is set. The stale PHPStan baseline entry for this exact error is removed.

  • Rop_Linkedin_Service::add_account_with_app() — an error payload without valid pages data reached array_pop( false ), a fatal TypeError on PHP 8. The payload is now validated (pages present, unserializes to a non-empty array, notify entry well-formed) and rejected with a logged error.

  • Rop_Rest_Api::add_account_li() — previously ignored the add_account_with_app() return value and registered the service even after a failed add. It now answers with a code 400 response pointing to the Revive Social log.

  • sign-in-btn.vue — the popup message handler parsed every message as account data. Malformed JSON and error payloads are now dropped with a logged error instead of being sent to the server and reloading the page.

  • E2E tests — new linkedin-error-handling.spec.js covers seven scenarios: missing, garbled, and empty payloads, pages without a notify entry, notify-only pages (asserting no service gets registered), the LinkedIn error landing in the plugin log, and a happy-path add that verifies the account is registered. The two malformed-payload tests fail with a fatal on the previous code.

LinkedIn account connection flow

flowchart LR
    A[LinkedIn popup<br/>posts message] --> B{Changed:<br/>valid account<br/>payload?}:::changed
    B -- No --> C[Log error,<br/>stop loading]
    B -- Yes --> D[REST<br/>add_account_li]
    D --> E{New:<br/>payload passes<br/>validation?}:::added
    E -- No --> F[Code 400 +<br/>Revive Social log]
    E -- Yes --> G[Account added]
    H[authorize<br/>token exchange fails] --> I[Changed:<br/>log real LinkedIn error]:::changed

    classDef added fill:#1a7f37,color:#fff,stroke:#116329,stroke-width:3px
    classDef changed fill:#9a6700,color:#fff,stroke:#5c3d00,stroke-width:3px,stroke-dasharray:6 3
Loading

Note

With ROP_DEBUG on (any non-production environment) a missing-key payload is answered by the pre-existing Rop_Exception_Handler debug output instead of the JSON 400 response. The e2e test accepts both shapes; production behavior is the 400 response.

QA

  1. Log in as an administrator and open the plugin dashboard at /wp-admin/admin.php?page=TweetOldPost (Revive Social entry in the admin menu). In the browser DevTools console, simulate the error payload LinkedIn hands back on a failed authorization:

    fetch(`${window.ropApiSettings.root}&req=add_account_li`, {
      method: 'POST',
      body: JSON.stringify({ id: 'czoyMToidXJuOmxpOnBlcnNvbjpFMkVURVNUIjs=', pages: btoa('error-not-account-data') }),
      headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': window.ropApiSettings.nonce },
    }).then(r => r.text()).then(console.log);

    Expect: a JSON response with "code":"400" (no critical-error page, no HTTP 500 fatal).

  2. Reload the dashboard page.

    Expect: the Accounts screen renders normally and LinkedIn still offers its sign-in button; no LinkedIn account was half-registered.

  3. With a real LinkedIn app configured, start Sign in to LinkedIn from the Accounts tab and cancel/deny the authorization on the LinkedIn side.

    Expect: the dashboard stays functional and the LinkedIn error is recorded in the plugin log (Revive Social dashboard → Logs) instead of a WordPress critical-error screen.

🤖 Generated with Claude Code

LinkedIn authorization failures could crash to the WordPress
critical-error screen instead of surfacing the LinkedIn error:

- authorize() called the non-existent Exception::getDescription() in
  its catch block, turning any caught error into a second fatal
- add_account_with_app() ran array_pop() on the result of
  unserialize() without validating the payload, fataling on PHP 8
  when the popup posts back an error payload instead of account data
- add_account_li() ignored the add_account_with_app() return value
  and registered the service regardless
- sign-in-btn.vue parsed every popup message as account data

Validation failures now log the LinkedIn error to the Revive Social
log and answer the REST call with a code 400 response.

Adds e2e coverage for the malformed-payload paths (red on the old
code) plus a happy-path guard, and drops the stale PHPStan baseline
entry for the fixed getDescription() call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pirate-bot

pirate-bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Plugin build for f452438 is ready 🛎️!

Adds regression tests for the remaining validation branches: empty
payload, pages without a notify entry, notify-only pages with no
accounts (asserting no service gets registered), the LinkedIn error
landing in the plugin log, and the happy path now verifies the
account is actually registered and exposed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lucadobrescu lucadobrescu self-assigned this Jul 28, 2026
@lucadobrescu lucadobrescu added the pr-checklist-skip Allow this Pull Request to skip checklist. label Jul 28, 2026
@pirate-bot pirate-bot added the pr-checklist-complete The Pull Request checklist is complete. (automatic label) label Jul 28, 2026
The add_account_with_app() validation guarantees the accounts loop
always runs, so PHPStan no longer reports 'Variable $account might
not be defined' and the baseline ignore became unmatched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-checklist-complete The Pull Request checklist is complete. (automatic label) pr-checklist-skip Allow this Pull Request to skip checklist.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants