Selaa lähdekoodia

main: handle stripe errors gracefully

brid 1 vuosi sitten
vanhempi
sitoutus
f9615a11c6
1 muutettua tiedostoa jossa 104 lisäystä ja 86 poistoa
  1. 104 86
      app/main.py

+ 104 - 86
app/main.py

@@ -727,105 +727,123 @@ async def stripe_webhook(request: Request, background_tasks: BackgroundTasks):
     """
     """
     main_logger.info("stripe-webhook => ...")
     main_logger.info("stripe-webhook => ...")
 
 
-    event = None
-    payload = await request.body()
-    sig_header = request.headers["stripe-signature"]
-
     try:
     try:
-        if os.getenv("ENV") == "production":
-            endpoint_secret = os.getenv("STRIPE_ENDPOINT_SECRET")
-        else:
-            endpoint_secret = os.getenv("STRIPE_TEST_ENDPOINT_SECRET")
+        event = None
+        payload = await request.body()
+        sig_header = request.headers["stripe-signature"]
 
 
-        event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret)
+        try:
+            if os.getenv("ENV") == "production":
+                endpoint_secret = os.getenv("STRIPE_ENDPOINT_SECRET")
+            else:
+                endpoint_secret = os.getenv("STRIPE_TEST_ENDPOINT_SECRET")
 
 
-    except ValueError as e:
-        main_logger.error(
-            f"stripe-webhook error: Webhook error while parsing basic request. {e}"
-        )
-        raise HTTPException(status_code=400, detail="Stripe payment error.")
+            event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret)
 
 
-    except stripe.error.SignatureVerificationError as e:
-        main_logger.error(
-            f"stripe-webhook error: Webhook signature verification failed. {e}"
-        )
-        raise HTTPException(status_code=400, detail="Stripe payment error.")
-
-    if event:
-        checkout = event["data"]["object"]
+        except ValueError as e:
+            main_logger.error(
+                f"stripe-webhook error: Webhook error while parsing basic request. {e}"
+            )
+            raise HTTPException(status_code=400, detail="Stripe payment error.")
 
 
-        if "client_reference_id" in checkout:
-            try:
-                status_res = update_status_order(
-                    event["type"],
-                    checkout["client_reference_id"],
-                    settings.git_repo,
-                    settings.local_db.filepath,
-                )
+        except stripe.error.SignatureVerificationError as e:
+            main_logger.error(
+                f"stripe-webhook error: Webhook signature verification failed. {e}"
+            )
+            raise HTTPException(status_code=400, detail="Stripe payment error.")
+
+        if event:
+            checkout = event["data"]["object"]
+
+            if "client_reference_id" in checkout:
+                try:
+                    status_res = update_status_order(
+                        event["type"],
+                        checkout["client_reference_id"],
+                        settings.git_repo,
+                        settings.local_db.filepath,
+                    )
 
 
-                if status_res is False:
-                    main_logger.error("stripe-webhook error: order could not be updated.")
-                    raise HTTPException(
-                        status_code=400, detail="Order could not be updated."
+                    if status_res is False:
+                        main_logger.error("stripe-webhook error: order could not be updated.")
+                        # Don't raise an exception, just log and continue
+                        #raise HTTPException(
+                        #    status_code=400, detail="Order could not be updated."
+                        #)
+                        # We still want to try updating inventory and sending email
+
+                except KeyError as e:
+                    main_logger.error(f"stripe-webhook error: Missing key in order data: {e}")
+                    # Continue processing - we want to still try to send the email
+
+                except Exception as e:
+                    main_logger.error(f"stripe-webhook error: Unexpected error updating order: {e}")
+                    # Continue processing
+
+                if event["type"] in [
+                    "checkout.session.completed",
+                    "checkout.session.async_payment_succeeded",
+                ]:
+                    order_id = checkout["client_reference_id"]
+                
+                    product_list = fetch_order_product_list(
+                        order_id, settings.git_repo, settings.local_db.filepath
                     )
                     )
+                
+                    if product_list:
+                        for product_info in product_list:
+                            # We need to read the product file and get the variation ID
+                            try:
+                                product = read_file(
+                                    settings.git_repo,
+                                    f"products/{product_info.filename}",
+                                    settings.document_match,
+                                    settings.block_types,
+                                )
+                                
+                                # Get the variation ID based on size and style
+                                product_variation_id = get_variation_id(product, product_info.size, product_info.style)
+                                
+                                update_product_inventory(
+                                    product_info.filename,
+                                    product_info.quantity,
+                                    product_variation_id,
+                                    settings,
+                                )
+                            except Exception as e:
+                                main_logger.error(f"stripe-webhook error: Failed to update inventory: {e}")
+                                # Continue processing other products
 
 
-            except KeyError as e:
-                main_logger.error(f"stripe-webhook error: Missing key in order data: {e}")
-                # Continue processing - we want to still try to send the email
+                    # -- send email
+                    try:
+                        email_settings = {
+                            "git_repo": settings.git_repo,
+                            "document_match": settings.document_match,
+                            "block_types": settings.block_types,
+                        }
 
 
-            except Exception as e:
-                main_logger.error(f"stripe-webhook error: Unexpected error updating order: {e}")
-                # Continue processing
+                        order = prepare_email_order(order_id, email_settings)
+                        await send_email(email_settings, order, background_tasks)
 
 
-            if event["type"] in [
-                "checkout.session.completed",
-                "checkout.session.async_payment_succeeded",
-            ]:
-                order_id = checkout["client_reference_id"]
+                    except Exception as e:
+                        main_logger.error(f"stripe-webhook error: Failed to send email: {e}")
+                        # Continue processing - we've already done inventory updates
 
 
-                product_list = fetch_order_product_list(
-                    order_id, settings.git_repo, settings.local_db.filepath
-                )
+                elif event["type"] == "checkout.session.async_payment_failed":
+                    main_logger.error(
+                        f"stripe-webhook error: Stripe payment error. {event['type']}"
+                    )
+                    raise HTTPException(status_code=400, detail="Stripe payment error.")
 
 
-                if product_list:
-                    for product_info in product_list:
-                        # We need to read the product file and get the variation ID
-                        product = read_file(
-                            settings.git_repo,
-                            f"products/{product_info.filename}",
-                            settings.document_match,
-                            settings.block_types,
-                        )
-                        
-                        # Get the variation ID based on size and style
-                        product_variation_id = get_variation_id(product, product_info.size, product_info.style)
-                        
-                        update_product_inventory(
-                            product_info.filename,
-                            product_info.quantity,
-                            product_info.product_variation_id,
-                            settings,
-                        )
-
-                # -- send email
-                email_settings = {
-                    "git_repo": settings.git_repo,
-                    "document_match": settings.document_match,
-                    "block_types": settings.block_types,
-                }
-
-                order = prepare_email_order(order_id, email_settings)
-                await send_email(email_settings, order, background_tasks)
-
-            elif event["type"] == "checkout.session.async_payment_failed":
-                main_logger.error(
-                    f"stripe-webhook error: Stripe payment error. {event['type']}"
-                )
-                raise HTTPException(status_code=400, detail="Stripe payment error.")
+        else:
+            main_logger.error(f"stripe-webhook error: Unhandled event type {event['type']}")
+            raise HTTPException(status_code=400, detail="Stripe payment error.")
 
 
-    else:
-        main_logger.error(f"stripe-webhook error: Unhandled event type {event['type']}")
-        raise HTTPException(status_code=400, detail="Stripe payment error.")
+    except Exception as e:
+        main_logger.error(f"stripe-webhook error: Unhandled exception: {e}")
+        import traceback
+        main_logger.error(traceback.format_exc())
+        # Still return success to prevent Stripe from retrying the webhook
 
 
     # -- return 200
     # -- return 200
     return {"success": True}
     return {"success": True}