Просмотр исходного кода

main: improve logging and error tracking

brid 1 год назад
Родитель
Сommit
98e8d3e46d
1 измененных файлов с 113 добавлено и 85 удалено
  1. 113 85
      app/main.py

+ 113 - 85
app/main.py

@@ -965,102 +965,130 @@ async def now_webhook(request: Request, background_tasks: BackgroundTasks):
     """NOW Payments IPN (Instant Payment Notification) webhook.
     Send email after successful payment confirmation.
     """
-    main_logger.info("now-webhook...")
+    main_logger.info("now-webhook: Starting processing")
 
-    payload = await request.json()
-    sig_header = request.headers["x-nowpayments-sig"]
-
-    if os.getenv("ENV") == "production":
-        ipn_secret_key = os.getenv("NOWPAYMENTS_IPN")
-    else:
-        ipn_secret_key = os.getenv("NOWPAYMENTS_SANDBOX_IPN")
-
-    is_verified = ipn_signature_check(ipn_secret_key, sig_header, payload)
-
-    if is_verified:
-        # check payment status, update order if
-        # status has changed (finished, expired, failed)
-        # send email if status: finished.
+    try:
+        payload = await request.json()
+        main_logger.info(f"now-webhook: Received payload with status: {payload.get('payment_status', 'unknown')}")
+        
+        sig_header = request.headers["x-nowpayments-sig"]
 
-        event_type = payload["payment_status"]
+        if os.getenv("ENV") == "production":
+            ipn_secret_key = os.getenv("NOWPAYMENTS_IPN")
+        else:
+            ipn_secret_key = os.getenv("NOWPAYMENTS_SANDBOX_IPN")
 
-        if event_type in ["finished", "expired", "failed"]:
-            if "payment_id" in payload:
-                order_id = payload["order_id"]
+        is_verified = ipn_signature_check(ipn_secret_key, sig_header, payload)
 
-                status_res = update_status_order(
-                    event_type,
-                    order_id,
-                    settings.git_repo,
-                    settings.local_db.filepath,
-                )
+        if is_verified:
+            # check payment status, update order if
+            # status has changed (finished, expired, failed)
+            # send email if status: finished.
+            event_type = payload["payment_status"]
+            main_logger.info(f"now-webhook: Processing verified event type: {event_type}")
 
-                if status_res is False:
-                    raise HTTPException(
-                        status_code=400, detail="Order could not be updated."
-                    )
+            if event_type in ["finished", "expired", "failed"]:
+                if "payment_id" in payload:
+                    order_id = payload["order_id"]
+                    main_logger.info(f"now-webhook: Processing order: {order_id}")
 
-                if event_type == "finished":
-                    product_list = fetch_order_product_list(
-                        order_id, settings.git_repo, settings.local_db.filepath
+                    status_res = update_status_order(
+                        event_type,
+                        order_id,
+                        settings.git_repo,
+                        settings.local_db.filepath,
                     )
 
-                    if product_list:
-                        for product_info in product_list:
-                            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"now-webhook error: Failed to update inventory: {e}")
-                                # Continue processing other products
-
-                    # -- send email
-                    try:
-                        email_settings = {
-                            "git_repo": settings.git_repo,
-                            "document_match": settings.document_match,
-                            "block_types": settings.block_types,
-                        }
-
+                    if status_res is False:
+                        main_logger.error(f"now-webhook: Failed to update order status for {order_id}")
+                        return JSONResponse(content={"success": False, "error": "Order could not be updated."}, status_code=400)
+
+                    if event_type == "finished":
+                        product_list = fetch_order_product_list(
+                            order_id, settings.git_repo, settings.local_db.filepath
+                        )
+                        
+                        main_logger.info(f"now-webhook: Found {len(product_list) if product_list else 0} products to update")
+
+                        if product_list:
+                            updated_products = 0
+                            for product_info in product_list:
+                                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)
+                                    
+                                    main_logger.info(f"now-webhook: Updating inventory for {product_info.filename}, variation: {product_variation_id}, quantity: {product_info.quantity}")
+                                    
+                                    update_product_inventory(
+                                        product_info.filename,
+                                        product_info.quantity,
+                                        product_variation_id,
+                                        settings,
+                                    )
+                                    updated_products += 1
+
+                                except Exception as e:
+                                    main_logger.error(f"now-webhook error: Failed to update inventory for {product_info.filename}: {e}")
+                                    import traceback
+                                    main_logger.error(traceback.format_exc())
+                                    # Continue processing other products
+                            
+                            main_logger.info(f"now-webhook: Successfully updated {updated_products} out of {len(product_list)} products")
+
+                        # -- send email
                         try:
-                            order = prepare_email_order(order_id, email_settings)
-                            await send_email(email_settings, order, background_tasks)
-                        except TypeError as e:
-                            main_logger.warning(f"now-webhook warning: Email preparation issue: {e}")
-
-                    except Exception as e:
-                        main_logger.error(f"now-webhook error: Failed to send email: {e}")
+                            email_settings = {
+                                "git_repo": settings.git_repo,
+                                "document_match": settings.document_match,
+                                "block_types": settings.block_types,
+                            }
 
-                elif event_type == "failed":
-                    main_logger.error(
-                        f"(NowPayments) Unhandled event type {event_type}"
-                    )
-                    raise HTTPException(
-                        status_code=400, detail="NOWPayments payment error."
-                    )
+                            try:
+                                main_logger.info(f"now-webhook: Preparing email for order {order_id}")
+                                order = prepare_email_order(order_id, email_settings)
+                                main_logger.info(f"now-webhook: Sending email for order {order_id}")
+                                await send_email(email_settings, order, background_tasks)
+                                main_logger.info(f"now-webhook: Email queued successfully")
+                            except TypeError as e:
+                                main_logger.warning(f"now-webhook warning: Email preparation issue: {e}")
+                                import traceback
+                                main_logger.error(traceback.format_exc())
+
+                        except Exception as e:
+                            main_logger.error(f"now-webhook error: Failed to send email: {e}")
+                            import traceback
+                            main_logger.error(traceback.format_exc())
+
+                    elif event_type == "failed":
+                        main_logger.error(f"now-webhook: Payment failed for order {order_id}")
+                        # We don't want to raise an exception here since we need to return a success response
+                        # Just log the error
+                else:
+                    main_logger.error("now-webhook: payment_id not in payload")
+                    return JSONResponse(content={"success": False, "error": "Payment ID missing"}, status_code=400)
             else:
-                main_logger.error("(NowPayments) payment_id not in payload")
-                raise HTTPException(
-                    status_code=400, detail="NOWPayments payment error."
-                )
-
+                main_logger.info(f"now-webhook: Event type {event_type} not processed (not in finished/expired/failed)")
+        else:
+            main_logger.error("now-webhook: Signature verification failed")
+            return JSONResponse(content={"success": False, "error": "Signature verification failed"}, status_code=400)
+            
+    except Exception as e:
+        main_logger.error(f"now-webhook error: Unhandled exception: {e}")
+        import traceback
+        main_logger.error(traceback.format_exc())
+        # Return success anyway to prevent NOW Payments from retrying constantly
+    
+    main_logger.info("now-webhook: Processing completed")
+    return JSONResponse(content={"success": True}, status_code=200)
 
 @app.get("/checkout/success", response_class=HTMLResponse)
 async def checkout_success(request: Request):