Skip to content

Improve checkout process with error handling and inventory management #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 46 additions & 20 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import os
from flask import Flask, request, json, abort
from flask import Flask, request, json, abort, jsonify
from flask_cors import CORS

import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration

class InsufficientInventoryError(Exception):
def __init__(self, message, product_id=None):
super().__init__(message)
self.product_id = product_id

sentry_sdk.init(
dsn="https://[email protected]/1316515",
integrations=[FlaskIntegration()],
Expand All @@ -30,20 +35,28 @@
obj['keyDoesntExist']

Inventory = {
'wrench': 1,
'nails': 1,
'hammer': 1
'wrench': 10,
'nails': 100,
'hammer': 5,
'4': 2 # Botana Voice with ID '4' and 2 in stock
}

def process_order(cart):
def process_order(cart_items, cart_quantities):
global Inventory
tempInventory = Inventory
for item in cart:
if Inventory[item['id']] <= 0:
raise Exception("Not enough inventory for " + item['id'])
else:
tempInventory[item['id']] -= 1
print 'Success: ' + item['id'] + ' was purchased, remaining stock is ' + str(tempInventory[item['id']])
tempInventory = Inventory.copy()
for item_in_cart in cart_items:
product_id = str(item_in_cart['id'])
if product_id not in tempInventory:
raise ValueError(f"Product ID '{product_id}' not found.")
requested_quantity = cart_quantities.get(product_id)
if not isinstance(requested_quantity, int) or requested_quantity <= 0:
raise ValueError(f"Invalid quantity for product ID '{product_id}'.")
available_stock = tempInventory[product_id]
if available_stock < requested_quantity:
raise InsufficientInventoryError(
f"Not enough inventory for product ID '{product_id}'.", product_id=product_id)
tempInventory[product_id] -= requested_quantity
print(f'Success: {product_id} was purchased, remaining stock is {tempInventory[product_id]}')
Inventory = tempInventory

@app.before_request
Expand All @@ -65,11 +78,24 @@

@app.route('/checkout', methods=['POST'])
def checkout():

order = json.loads(request.data)
print "Processing order for: " + order["email"]
cart = order["cart"]

process_order(cart)

return 'Success'
try:
order_data = request.get_json()
print(f"Processing order for: {order_data['form']['email']}")
cart = order_data["cart"]
cart_items = cart['items']
cart_quantities = cart['quantities']

process_order(cart_items, cart_quantities)
return jsonify({"message": "Order successful"}), 200
except InsufficientInventoryError as e:
return jsonify({
"error": "InsufficientInventory",
"message": str(e),
"product_id": e.product_id
}), 409
Comment on lines +91 to +95

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 6 days ago

To fix the issue, the exception messages should not be directly included in the response sent to the client. Instead, a generic error message should be returned, and the detailed exception message should be logged for internal use. This ensures that sensitive information is not exposed to external users while still allowing developers to debug issues using the logs.

The changes required are:

  1. Replace the str(e) usage in the JSON response with a generic error message.
  2. Log the exception message internally using sentry_sdk.capture_exception(e) or another logging mechanism.

Suggested changeset 1
app.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -90,5 +90,6 @@
     except InsufficientInventoryError as e:
+        sentry_sdk.capture_exception(e)
         return jsonify({
             "error": "InsufficientInventory",
-            "message": str(e),
+            "message": "Not enough inventory for the requested product.",
             "product_id": e.product_id
@@ -96,3 +97,4 @@
     except ValueError as e:
-        return jsonify({"error": "BadRequest", "message": str(e)}), 400
+        sentry_sdk.capture_exception(e)
+        return jsonify({"error": "BadRequest", "message": "Invalid request data."}), 400
     except Exception as e:
EOF
@@ -90,5 +90,6 @@
except InsufficientInventoryError as e:
sentry_sdk.capture_exception(e)
return jsonify({
"error": "InsufficientInventory",
"message": str(e),
"message": "Not enough inventory for the requested product.",
"product_id": e.product_id
@@ -96,3 +97,4 @@
except ValueError as e:
return jsonify({"error": "BadRequest", "message": str(e)}), 400
sentry_sdk.capture_exception(e)
return jsonify({"error": "BadRequest", "message": "Invalid request data."}), 400
except Exception as e:
Copilot is powered by AI and may make mistakes. Always verify output.
except ValueError as e:
return jsonify({"error": "BadRequest", "message": str(e)}), 400

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 6 days ago

To fix the issue, we will replace the direct use of str(e) in the response with a sanitized and generic error message. This ensures that no sensitive information is exposed to the user. Specifically:

  1. Replace the str(e) in the ValueError handler with a generic message like "Invalid input provided.".
  2. Log the original exception message (str(e)) for debugging purposes using sentry_sdk.capture_exception(e) or another logging mechanism.

This change will ensure that sensitive information is not exposed to the user while still allowing developers to debug the issue using the logs.


Suggested changeset 1
app.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -96,3 +96,4 @@
     except ValueError as e:
-        return jsonify({"error": "BadRequest", "message": str(e)}), 400
+        sentry_sdk.capture_exception(e)  # Log the original exception
+        return jsonify({"error": "BadRequest", "message": "Invalid input provided."}), 400
     except Exception as e:
EOF
@@ -96,3 +96,4 @@
except ValueError as e:
return jsonify({"error": "BadRequest", "message": str(e)}), 400
sentry_sdk.capture_exception(e) # Log the original exception
return jsonify({"error": "BadRequest", "message": "Invalid input provided."}), 400
except Exception as e:
Copilot is powered by AI and may make mistakes. Always verify output.
except Exception as e:
# Fallback for unexpected errors
sentry_sdk.capture_exception(e)
return jsonify({"error": "InternalServerError", "message": "An unexpected error occurred."}), 500
Loading