Preserve the caught error in the billing-degradation error boundaries (#1741)

This commit is contained in:
Konsti Wohlwend 2026-07-08 09:26:17 -07:00 committed by GitHub
parent 1837f5db2a
commit 7a78085a49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 11 deletions

View File

@ -333,16 +333,16 @@ export function ErrorDisplay({ error, onRetry }: { error: unknown, onRetry: () =
* error escape to the page. `Suspense` keeps the banner from blocking the page
* while its data loads.
*/
function BillingBannerErrorFallback() {
function BillingBannerErrorFallback({ location, error }: { location: string, error: unknown }) {
useEffect(() => {
captureError("analytics-limit-banner:billing-read-failed", new Error("Failed to load plan-limit banner data; hiding the banner"));
}, []);
captureError(location, error);
}, [location, error]);
return null;
}
function ResilientBillingBanner(props: { children: ReactNode }) {
function ResilientBillingBanner(props: { children: ReactNode, location: string }) {
return (
<ErrorBoundary errorComponent={BillingBannerErrorFallback}>
<ErrorBoundary errorComponent={({ error }) => <BillingBannerErrorFallback location={props.location} error={error} />}>
<Suspense fallback={null}>
{props.children}
</Suspense>
@ -356,7 +356,7 @@ function ResilientBillingBanner(props: { children: ReactNode }) {
*/
export function AnalyticsEventLimitBanner() {
return (
<ResilientBillingBanner>
<ResilientBillingBanner location="analytics-limit-banner:billing-read-failed">
<AnalyticsEventLimitBannerContent />
</ResilientBillingBanner>
);
@ -387,7 +387,7 @@ function AnalyticsEventLimitBannerContent() {
*/
export function SessionReplayLimitBanner() {
return (
<ResilientBillingBanner>
<ResilientBillingBanner location="session-replay-limit-banner:billing-read-failed">
<SessionReplayLimitBannerContent />
</ResilientBillingBanner>
);

View File

@ -199,7 +199,7 @@ function AddCustomOidcButton({ onClick }: { onClick: () => void }) {
// read failure (or while it loads) we report it and fall back to the locked
// (non-Team) state, which is the same safe default as having no owner team.
return (
<ErrorBoundary errorComponent={() => <AddCustomOidcButtonPlanReadFailed onClick={onClick} />}>
<ErrorBoundary errorComponent={({ error }) => <AddCustomOidcButtonPlanReadFailed onClick={onClick} error={error} />}>
<Suspense fallback={<AddCustomOidcButtonDisabled onClick={onClick} isTeamPlanOrAbove={false} />}>
<AddCustomOidcButtonInner team={ownerTeam} onClick={onClick} />
</Suspense>
@ -207,10 +207,10 @@ function AddCustomOidcButton({ onClick }: { onClick: () => void }) {
);
}
function AddCustomOidcButtonPlanReadFailed({ onClick }: { onClick: () => void }) {
function AddCustomOidcButtonPlanReadFailed({ onClick, error }: { onClick: () => void, error: unknown }) {
useEffect(() => {
captureError("auth-methods:custom-oidc-plan-gate", new Error("Failed to load owner team plan for the custom OIDC gate; defaulting to locked"));
}, []);
captureError("auth-methods:custom-oidc-plan-gate", error);
}, [error]);
return <AddCustomOidcButtonDisabled onClick={onClick} isTeamPlanOrAbove={false} />;
}