{"record":{"id":"4292397486169b67","repo":"hcengineering/platform","slug":"internal-server-error-429239","errorCode":null,"errorMessage":"Internal server error","messagePattern":"Internal server error","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"services/payment/pod-payment/src/providers/stripe/webhook.ts","lineNumber":100,"sourceCode":"            const subscriptionEvent = await createSubscriptionEventFromInvoiceEvent(ctx, stripe, event)\n            if (subscriptionEvent == null) return\n\n            await handleSubscriptionUpdated(ctx, accountsUrl, serviceToken, subscriptionEvent)\n          } catch (err) {\n            ctx.error('Failed to process Stripe invoice event', { event, err })\n          }\n        })()\n        break\n      }\n      default: {\n        ctx.info('Unhandled Stripe webhook event type', { type: event.type })\n      }\n    }\n\n    res.status(200).json({ received: true })\n  } catch (err) {\n    ctx.error('Failed to process Stripe webhook', { err })\n    res.status(500).json({ error: 'Internal server error' })\n  }\n}\n\n/**\n * Handle subscription.created/updated/deleted\n */\nasync function handleSubscriptionUpdated (\n  ctx: MeasureContext,\n  accountsUrl: string,\n  serviceToken: string,\n  event: Stripe.Event\n): Promise<void> {\n  const subscription = event.data.object as Stripe.Subscription\n  if (subscription == null) {\n    ctx.error('Missing subscription data', { event })\n    throw new Error('Missing subscription data')\n  }\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/payment/pod-payment/src/providers/stripe/webhook.ts#L82-L118","documentation":"Catch-all in handleStripeWebhook: after successful signature verification, any exception during event routing or handling (or constructing Stripe-related state) results in HTTP 500 'Internal server error'.","triggerScenarios":"A subscription event handler throws (DB failure, missing customer/price mapping, unexpected payload shape); unrecognized event type reaching code that assumes a structure; error thrown while building the response path after res already touched.","commonSituations":"Stripe schema changes adding fields/removing assumptions; DB outage during event processing; duplicate event replay hitting unique constraints.","solutions":["Inspect server logs (ctx.error 'Failed to process Stripe webhook') for the root err and fix it","Replay the event via Stripe dashboard or stripe CLI after the fix","Make handlers idempotent (event.id dedupe) to survive Stripe's retries","Add a default case that acknowledges unknown event types instead of throwing"],"exampleFix":"// before\ndefault:\n  throw new Error(`unhandled ${event.type}`)\n// after\ndefault:\n  ctx.warn('Unhandled Stripe event', { type: event.type })","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await routeEvent(event)\n  res.status(200).json({ received: true })\n} catch (err) {\n  ctx.error('Failed to process Stripe webhook', { err })\n  res.status(500).json({ error: 'Internal server error' })\n}","preventionTips":["Deduplicate on event.id for idempotent handling","Acknowledge unknown event types with 200 + warn","Alert on 500 responses and replay events after fixes","Keep handler logic defensive against Stripe schema changes"],"tags":["webhook","unhandled-exception","http-500","stripe"],"backgroundTag":"webhook-handler-crash","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}