Skip to content

Log wordpress-rs request errors via AppLog and centralize WpComApiClient construction#22979

Open
oguzkocer wants to merge 3 commits into
trunkfrom
wpcom-api-client-error-logging
Open

Log wordpress-rs request errors via AppLog and centralize WpComApiClient construction#22979
oguzkocer wants to merge 3 commits into
trunkfrom
wpcom-api-client-error-logging

Conversation

@oguzkocer

@oguzkocer oguzkocer commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Description

Failed wordpress-rs requests were not surfaced anywhere in the app's own diagnostics. This PR routes them to AppLog (so they appear in the in-app log viewer and crash-reporting breadcrumbs under the API tag) and, as a follow-up, consolidates WpComApiClient construction so that wiring lives in a single place.

The PR is split into two independent commits. The second is a cleanup and can be dropped without affecting the first.

Changes

1. Route request errors to AppLog

  • Pass RequestErrorLogger { AppLog.e(AppLog.T.API, it) } into every WpComApiClient / WpApiClient construction site (WpComApiClientProvider, the three constructions in fluxc's WpApiClientProvider, and the two ViewModels that built clients directly).

Self-contained and shippable on its own.

2. Centralize WpComApiClient construction

  • Route DataViewViewModel (and its SubscribersViewModel, TermsViewModel, ApplicationPasswordsViewModel subclasses) and AddSubscribersViewModel through WpComApiClientProvider.getWpComApiClient(token) instead of constructing WpComApiClient directly.
  • Drops the per-call auth/interceptor/logger boilerplate and the now-unused trackNetworkRequestsInterceptor / networkAvailabilityProvider constructor params from those ViewModels (a net simplification).
  • WpComApiClientProvider now attaches TrackNetworkRequestsInterceptor itself, so the moved clients keep their network-inspector behavior.

Behavior change

Because WpComApiClientProvider now attaches TrackNetworkRequestsInterceptor, all of its consumers (StatsDataSourceImpl, NewDomainsSearchRepository, HESupportRepository, AIBotSupportRepository, plus the migrated ViewModels) become inspectable via the in-app Track network requests debug tool. This is preference-gated (off unless the user enables it) and makes coverage uniform across WP.com clients.

Testing instructions

  1. Error logging — trigger a failed WP.com request (e.g. temporarily force the Me → Domains → Find a domain request to fail) and confirm a WordPress-API-tagged error appears in logcat / the in-app log viewer, e.g. E/WordPress-API: UnknownError(status=400, method=GET, url=…, response=…).
  2. Migrated screens — verify the screens backed by the migrated ViewModels still work end to end: Me → Subscribers (and Add subscribers), Terms (categories/tags), and Application Passwords.
  3. Network tracker (optional) — enable Track network requests in debug settings and confirm WP.com requests from the above flows show up.

@oguzkocer oguzkocer added this to the 26.9 milestone Jun 13, 2026
@dangermattic

dangermattic commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator
1 Warning
⚠️ This PR is assigned to the milestone 26.9. This milestone is due in less than 4 days.
Please make sure to get it merged by then or assign it to a milestone with a later deadline.

Generated by 🚫 Danger

@wpmobilebot

wpmobilebot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Project dependencies changes

list
! Upgraded Dependencies
rs.wordpress.api:android:trunk-97d62ffff2983c0c71f2bbf95254156eba9aa57c, (changed from trunk-96105487c29b4205f25ff722ec80704ef8baa263)
rs.wordpress.api:kotlin:trunk-97d62ffff2983c0c71f2bbf95254156eba9aa57c, (changed from trunk-96105487c29b4205f25ff722ec80704ef8baa263)
tree
 +--- project :libs:fluxc
-|    \--- rs.wordpress.api:android:trunk-96105487c29b4205f25ff722ec80704ef8baa263
-|         +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
-|         +--- com.squareup.okhttp3:okhttp-tls:5.4.0
-|         |    +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
-|         |    +--- com.squareup.okio:okio:3.17.0 (*)
-|         |    \--- com.squareup.okhttp3:okhttp:5.4.0 (*)
-|         +--- net.java.dev.jna:jna:5.19.0
-|         +--- rs.wordpress.api:kotlin:trunk-96105487c29b4205f25ff722ec80704ef8baa263
-|         |    +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
-|         |    +--- com.squareup.okhttp3:okhttp-tls:5.4.0 (*)
-|         |    +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 -> 1.11.0 (*)
-|         |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
-|         \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
+|    \--- rs.wordpress.api:android:trunk-97d62ffff2983c0c71f2bbf95254156eba9aa57c
+|         +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
+|         +--- com.squareup.okhttp3:okhttp-tls:5.4.0
+|         |    +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
+|         |    +--- com.squareup.okio:okio:3.17.0 (*)
+|         |    \--- com.squareup.okhttp3:okhttp:5.4.0 (*)
+|         +--- net.java.dev.jna:jna:5.19.0
+|         +--- rs.wordpress.api:kotlin:trunk-97d62ffff2983c0c71f2bbf95254156eba9aa57c
+|         |    +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
+|         |    +--- com.squareup.okhttp3:okhttp-tls:5.4.0 (*)
+|         |    +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 -> 1.11.0 (*)
+|         |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
+|         \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
-\--- rs.wordpress.api:android:trunk-96105487c29b4205f25ff722ec80704ef8baa263 (*)
+\--- rs.wordpress.api:android:trunk-97d62ffff2983c0c71f2bbf95254156eba9aa57c (*)

@wpmobilebot

wpmobilebot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

App Icon📲 You can test the changes from this Pull Request in WordPress Android by scanning the QR code below to install the corresponding build.

App NameWordPress Android
Build TypeDebug
Versionpr22979-f9b411c
Build Number1495
Application IDorg.wordpress.android.prealpha
Commitf9b411c
Installation URL2lvln62l0auog
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot

wpmobilebot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

App Icon📲 You can test the changes from this Pull Request in Jetpack Android by scanning the QR code below to install the corresponding build.

App NameJetpack Android
Build TypeDebug
Versionpr22979-f9b411c
Build Number1495
Application IDcom.jetpack.android.prealpha
Commitf9b411c
Installation URL1bkq6hchpe86g
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

Bump wordpress-rs to the PR #1398 build that adds RequestErrorLogger, and
wire RequestErrorLogger { AppLog.e(T.API, it) } into every WpComApiClient and
WpApiClient construction site. Failed requests are now logged under the API
tag (and crash-reporting breadcrumbs) instead of going unlogged.
Route DataViewViewModel (with its SubscribersViewModel, TermsViewModel, and
ApplicationPasswordsViewModel subclasses) and AddSubscribersViewModel through
WpComApiClientProvider instead of constructing WpComApiClient directly. Keeps
the RequestErrorLogger wiring in one place and drops the per-call auth/
interceptor/logger boilerplate.

The provider now attaches TrackNetworkRequestsInterceptor, so all its consumers
(previously only these ViewModels) become inspectable via the in-app network
tracker when that debug setting is enabled.
@oguzkocer oguzkocer force-pushed the wpcom-api-client-error-logging branch from 7495634 to 6e3e0c5 Compare June 15, 2026 11:45
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 20.00000% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 37.44%. Comparing base (bf01de3) to head (f9b411c).

Files with missing lines Patch % Lines
...fluxc/network/rest/wpapi/rs/WpApiClientProvider.kt 0.00% 4 Missing ⚠️
...droid/networking/restapi/WpComApiClientProvider.kt 0.00% 3 Missing ⚠️
.../android/ui/subscribers/AddSubscribersViewModel.kt 0.00% 2 Missing ⚠️
...plicationpassword/ApplicationPasswordsViewModel.kt 0.00% 1 Missing ⚠️
...wordpress/android/ui/dataview/DataViewViewModel.kt 66.66% 0 Missing and 1 partial ⚠️
...ess/android/ui/subscribers/SubscribersViewModel.kt 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk   #22979      +/-   ##
==========================================
- Coverage   37.44%   37.44%   -0.01%     
==========================================
  Files        2325     2325              
  Lines      125214   125208       -6     
  Branches    17159    17159              
==========================================
- Hits        46884    46881       -3     
+ Misses      74523    74520       -3     
  Partials     3807     3807              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@oguzkocer oguzkocer marked this pull request as ready for review June 15, 2026 12:19
@oguzkocer oguzkocer requested a review from a team as a code owner June 15, 2026 12:19
@oguzkocer oguzkocer requested review from adalpari and removed request for a team June 15, 2026 12:19
private val wpComClients = mutableMapOf<Long, WpApiClient>()
private val selfHostedClients = mutableMapOf<Int, WpApiClient>()

private val errorLogger = RequestErrorLogger { AppLog.e(AppLog.T.API, it) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

❓ Can't the RequestErrorLogger be injected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What would be the point of injecting it?

@adalpari adalpari Jun 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm thinking on detaching the class from the RequestErrorLogger, so it's more testable and non-dependent.
But also, I see WpComApiClientProvider creating the object again, so the object creation could be centralised.

Not a blocker, though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

All it does is this AppLog.e(AppLog.T.API, it). Injecting that seems like too much ceremony and there is nothing to test.

If we add any logic to it, it'll make sense, but in my opinion it's premature to do it now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fair enough 👍

@adalpari

Copy link
Copy Markdown
Contributor

Claude pointed a couple of privacy concerns, so it would be great to double-check them:

  - url for WP.com requests can carry query parameters; response is the failed-response body, which may contain account/PII data.
  - Unlike TrackNetworkRequestsInterceptor (which redacts Authorization, Cookie, X-WP-Nonce and xmlrpc.php/wp-login.php bodies), this error path has no redaction. Please confirm the rs error objects never include bearer tokens or sensitive response bodies before they land in breadcrumbs. If they can, consider sanitizing in the lambda.

@oguzkocer

Copy link
Copy Markdown
Contributor Author

@adalpari Any reason you merged trunk to this branch? I have another branch on top of this, so it'll make it slightly more annoying to rebase, but more importantly, it's generally unexpected to modify someone else's branch, so I'm surprised.

@adalpari

Copy link
Copy Markdown
Contributor

@adalpari Any reason you merged trunk to this branch? I have another branch on top of this, so it'll make it slightly more annoying to rebase, but more importantly, it's generally unexpected to modify someone else's branch, so I'm surprised.

Oh boy... sorry I hit the button on the wrong PR :(

@oguzkocer

Copy link
Copy Markdown
Contributor Author

Claude pointed a couple of privacy concerns, so it would be great to double-check them:

  • url for WP.com requests can carry query parameters; response is the failed-response body, which may contain account/PII data.
  • Unlike TrackNetworkRequestsInterceptor (which redacts Authorization, Cookie, X-WP-Nonce and xmlrpc.php/wp-login.php bodies), this error path has no redaction. Please confirm the rs error objects never include bearer tokens or sensitive response bodies before they land in breadcrumbs. If they can, consider sanitizing in the lambda.

This is a fair point. I looked into it again and verified that we do not log the headers which is the important thing. The main risk with the current implementation is the failed response body and to a lesser extent the query params being logged.

If we want to be extra sure, we can strip the url params and only include the error information. wordpress-rs will still be the one controlling what's being logged, so that might be a slight nag but since it's our library, it's probably fine.

@jkmassel Any thoughts on whether we want to keep the full details for the logs or go with a leaner log in favor of extra security?

@adalpari

Copy link
Copy Markdown
Contributor

I looked into it again and verified that we do not log the headers which is the important thing.

If we are sure about that, then I think it should be enough, + maybe query params?

Just a note that when we worked on the network logger, we had to hide the body on RPC calls because it was exposing sensitive data. I guess it doesn't apply here, but just to have it in mind.

@oguzkocer

Copy link
Copy Markdown
Contributor Author

Just a note that when we worked on the network logger, we had to hide the body on RPC calls because it was exposing sensitive data. I guess it doesn't apply here, but just to have it in mind.

It's unlikely to be an issue here especially since it's response body, but it might. Since it's out of our control, it's probably safer to not log the response.

For the query params, it's probably fine to log and could be useful for debugging, but I can see an argument for being extra cautious and stripping those out as well.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants