Skip to content

feat: emit :reauthorization_required telemetry event - #2

Closed
helording wants to merge 1 commit into
surface-token-on-persist-failurefrom
reauthorization-required-telemetry
Closed

feat: emit :reauthorization_required telemetry event#2
helording wants to merge 1 commit into
surface-token-on-persist-failurefrom
reauthorization-required-telemetry

Conversation

@helording

Copy link
Copy Markdown
Owner

What

Adds a dedicated telemetry event, [:ex_shopify_app, :access_token, :refresh, :reauthorization_required], that fires whenever an access-token operation resolves to :reauthorization_required — i.e. the token chain can no longer be refreshed and the merchant must relaunch the app to reauthorize.

Why

:reauthorization_required is the one outcome a host app genuinely needs to act on (prompt re-auth, alert, flag the shop), but until now it was easy to miss:

  • valid_token/2 short-circuits on an already-expired refresh token before refresh_token/2, so it emitted no telemetry at all.
  • On the refresh paths, the signal was only available buried in the :stop event's :result metadata, alongside every successful refresh — there was no event a handler could subscribe to directly.

How

A single public emitter, Telemetry.reauthorization_required/1, is now called on every path that yields the result:

  • valid_token/2's early short-circuit (explicit call, since it never enters the refresh span).
  • The locked refresh re-checking expiry under the row lock, and Shopify rejecting a refresh with invalid_grant — both flow through refresh_stop/3, which emits the event when the classified result is :reauthorization_required.

Metadata carries :shopify_domain only — never token values, consistent with the other events in this module.

Tests

Adds coverage for all three paths in RepoTest (already-expired refresh token via valid_token/2 and via refresh_token/2, and a Shopify invalid_grant). Full suite green (63 tests), mix format clean, compiles with --warnings-as-errors.

🤖 Generated with Claude Code

Surface a dedicated `[:ex_shopify_app, :access_token, :refresh,
:reauthorization_required]` event whenever a call resolves to
`:reauthorization_required`, so host apps can react to chains that can no
longer be refreshed (the merchant must relaunch the app to reauthorize).

It fires on every path that produces the result:

  * `valid_token/2` short-circuiting on an already-expired refresh token
    before any HTTP call (previously emitted no telemetry at all);
  * the locked refresh re-checking expiry under the row lock;
  * Shopify rejecting a refresh with `invalid_grant`.

The latter two flow through `refresh_stop/3`, which now emits the event when
the classified result is `:reauthorization_required`. Metadata carries
`:shopify_domain` only — never token values.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@helording

Copy link
Copy Markdown
Owner Author

Superseded by the upstream PR against NexPB/ex_shopify_app, stacked on NexPB#3 (keepalive-refresher).

@helording helording closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant