[PM-38874] fix: Keep Admin org page accessible when Stripe customer is deleted#7913
[PM-38874] fix: Keep Admin org page accessible when Stripe customer is deleted#7913kdenney wants to merge 8 commits into
Conversation
…-38874) When GetBillingAsync succeeded but GetBillingHistoryAsync threw, the catch left BillingInfo non-null while BillingHistoryInfo stayed null. The view guard only checked BillingInfo, so _BillingInformation still rendered and dereferenced BillingHistoryInfo, throwing an NRE and returning a 500, the exact failure this fix set out to prevent. Reset both billing values in the catch so billing loads as a unit, and add BillingHistoryInfo to the view conditional as defense-in-depth. Add a test covering the GetBillingHistoryAsync-throws path.
…ilure on Admin org page (PM-38874)
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Reviewed a bugfix that keeps the Admin org Edit page accessible when an organization's Stripe customer has been deleted. The billing loads are wrapped in a try/catch that resets both Code Review DetailsNo blocking findings. Notes from analysis:
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7913 +/- ##
==========================================
+ Coverage 61.35% 61.37% +0.01%
==========================================
Files 2236 2236
Lines 98547 98576 +29
Branches 8911 8912 +1
==========================================
+ Hits 60468 60501 +33
+ Misses 35943 35939 -4
Partials 2136 2136 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-38874
📔 Objective
Loading the edit page for an organization in the Admin portal calls
GetBillingAsyncandGetBillingHistoryAsync, both of which hit Stripe to fetch the customer. When an organization's Stripe customer has been deleted, these calls throw and the entire Edit page fails to render, leaving an admin with no way to reach the org and correct itsGateway Customer ID.The Edit page now loads even when billing info cannot be retrieved.
GetBillingAsync/GetBillingHistoryAsyncare wrapped in a try/catch that resets both values to null on failure, and the Billing Information section is hidden when either is null. Two failure cases are distinguished:resource_missingerror (the customer no longer exists) sets aTempData["Warning"]message telling the admin they can set a valid Gateway Customer ID.TempData["Error"]message suggesting a reload and contacting support.Note: The Admin layout previously rendered
TempData["Error"]andTempData["Success"]toasts but notTempData["Warning"]. This adds atoastr.warningblock so the new warning surfaces. As a side effect, warning messages that were already being set on the organization, provider, and user edit pages (all of the "updated successfully, but a follow-up Stripe/email step failed" variety) were previously set but never displayed, and now appear as warning toasts. These only fire when the corresponding secondary operation fails; normal saves are unaffected.Unit tests cover the missing-customer path (both when the initial billing call fails and when the history call fails after billing succeeds) and the generic-error path.
📸 Screenshots