From 65ccd5a89d7a94279be49965a0872f868c53ab38 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 16 Sep 2026 12:11:25 -0400 Subject: [PATCH] Enhance error handling for subscription lifecycle events in billing hooks --- .../hooks/handleSubscriptionCreated.ts | 7 +++++ .../hooks/handleSubscriptionDeleted.ts | 12 +++++++-- .../hooks/handleSubscriptionUpdated.ts | 26 ++++++++++++++----- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/server/private/routers/billing/hooks/handleSubscriptionCreated.ts b/server/private/routers/billing/hooks/handleSubscriptionCreated.ts index f09a5d215..7cf21577a 100644 --- a/server/private/routers/billing/hooks/handleSubscriptionCreated.ts +++ b/server/private/routers/billing/hooks/handleSubscriptionCreated.ts @@ -276,6 +276,13 @@ export async function handleSubscriptionCreated( logger.debug(`Fossorial API response: ${JSON.stringify(data)}`); + if (!response.ok || !data.success) { + logger.error( + `Fossorial API returned ${response.status} when setting paid-for for orgId ${customer.orgId} and subscription ID ${subscription.id}: ${JSON.stringify(data)}` + ); + return; + } + if (customer.email) { logger.debug( `Sending license key email to ${customer.email} for subscription ${subscription.id}` diff --git a/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts b/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts index c12889479..7f7e0838e 100644 --- a/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts +++ b/server/private/routers/billing/hooks/handleSubscriptionDeleted.ts @@ -125,7 +125,7 @@ export async function handleSubscriptionDeleted( `Handling license subscription deletion for orgId ${customer.orgId} and subscription ID ${subscription.id}` ); try { - await fetch( + const invalidateResponse = await fetch( `${privateConfig.getRawPrivateConfig().server.fossorial_api}/api/v1/license-internal/enterprise/invalidate`, { method: "POST", @@ -137,10 +137,18 @@ export async function handleSubscriptionDeleted( }, body: JSON.stringify({ orgId: customer.orgId, - licenseKeyId: subscription.metadata.licenseKeyId + licenseKeyId: parseInt( + subscription.metadata.licenseKeyId + ) }) } ); + + if (!invalidateResponse.ok) { + logger.error( + `Fossorial API returned ${invalidateResponse.status} when invalidating license for orgId ${customer.orgId} and subscription ID ${subscription.id}: ${await invalidateResponse.text()}` + ); + } } catch (error) { logger.error( `Error notifying Fossorial API of license subscription deletion for orgId ${customer.orgId} and subscription ID ${subscription.id}:`, diff --git a/server/private/routers/billing/hooks/handleSubscriptionUpdated.ts b/server/private/routers/billing/hooks/handleSubscriptionUpdated.ts index 935f90cc2..82d0ea248 100644 --- a/server/private/routers/billing/hooks/handleSubscriptionUpdated.ts +++ b/server/private/routers/billing/hooks/handleSubscriptionUpdated.ts @@ -324,7 +324,7 @@ export async function handleSubscriptionUpdated( effectiveStatus == "incomplete_expired" ) { try { - await fetch( + const invalidateResponse = await fetch( `${privateConfig.getRawPrivateConfig().server.fossorial_api}/api/v1/license-internal/enterprise/invalidate`, { method: "POST", @@ -336,11 +336,18 @@ export async function handleSubscriptionUpdated( }, body: JSON.stringify({ orgId: customer.orgId, - licenseKeyId: + licenseKeyId: parseInt( subscription.metadata.licenseKeyId + ) }) } ); + + if (!invalidateResponse.ok) { + logger.error( + `Fossorial API returned ${invalidateResponse.status} when invalidating license for orgId ${customer.orgId} and subscription ID ${subscription.id}: ${await invalidateResponse.text()}` + ); + } } catch (error) { logger.error( `Error notifying Fossorial API of license subscription deletion for orgId ${customer.orgId} and subscription ID ${subscription.id}:`, @@ -383,7 +390,7 @@ export async function handleSubscriptionUpdated( 5 * 24 * 60 * 60; try { - await fetch( + const extendResponse = await fetch( `${privateConfig.getRawPrivateConfig().server.fossorial_api}/api/v1/license-internal/enterprise/extend`, { method: "POST", @@ -399,9 +406,16 @@ export async function handleSubscriptionUpdated( }) } ); - logger.info( - `Extended license ${licenseKeyId} for subscription ${subscription.id} to expire at ${expiresAt}.` - ); + + if (!extendResponse.ok) { + logger.error( + `Fossorial API returned ${extendResponse.status} when extending license ${licenseKeyId} for subscription ${subscription.id}: ${await extendResponse.text()}` + ); + } else { + logger.info( + `Extended license ${licenseKeyId} for subscription ${subscription.id} to expire at ${expiresAt}.` + ); + } } catch (error) { logger.error( `Error notifying Fossorial API of license renewal for subscription ${subscription.id}:`,