Skip to content

Implement order processing with inventory management and error handling #22

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
77 changes: 56 additions & 21 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import os
from flask import Flask, request, json, abort
from flask import Flask, request, json, abort, jsonify
from flask_cors import CORS

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

import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration

Expand Down Expand Up @@ -30,21 +35,37 @@
obj['keyDoesntExist']

Inventory = {
'wrench': 1,
'nails': 1,
'hammer': 1
'wrench': 10,
'nails': 100,
'hammer': 5,
'1': 20, # Snake Plant
'2': 15, # Monstera
'3': 10, # ZZ Plant
'4': 2, # Botana Voice
'5': 8 # Ficus
}

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']])
Inventory = tempInventory
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, quantity: {requested_quantity}, remaining stock: {tempInventory[product_id]}")

Inventory = tempInventory

@app.before_request
def sentry_event_context():
Expand All @@ -65,11 +86,25 @@

@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 = json.loads(request.data)
print("Processing order for: " + order_data.get("email", "unknown"))

cart = order_data.get("cart", {})
cart_items = cart.get("items", [])
cart_quantities = cart.get("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 # Use 409 Conflict
Comment on lines +100 to +104

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 16 days ago

To fix the issue, we will modify the code to avoid exposing the exception message directly to the user. Instead, we will provide a generic error message while logging the detailed exception message for debugging purposes. This ensures that sensitive information is not exposed to external users while still allowing developers to diagnose issues.

Steps to implement the fix:

  1. Replace the direct use of str(e) in the JSON response with a generic error message.
  2. Log the detailed exception message using sentry_sdk.capture_exception(e) or another logging mechanism.
  3. Ensure that the response remains informative enough for the user without exposing sensitive details.
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
@@ -99,5 +99,6 @@
     except InsufficientInventoryError as e:
+        sentry_sdk.capture_exception(e)
         return jsonify({
             "error": "InsufficientInventory",
-            "message": str(e),
+            "message": "The requested product is out of stock.",
             "product_id": e.product_id
@@ -105,3 +106,4 @@
     except ValueError as e:
-        return jsonify({"error": "BadRequest", "message": str(e)}), 400  # Use 400 Bad Request
+        sentry_sdk.capture_exception(e)
+        return jsonify({"error": "BadRequest", "message": "Invalid request data."}), 400  # Use 400 Bad Request
     except Exception as e:
@@ -109,2 +111,3 @@
         sentry_sdk.capture_exception(e)
+        sentry_sdk.capture_exception(e)
         return jsonify({"error": "InternalServerError", "message": "An unexpected error occurred."}), 500
EOF
@@ -99,5 +99,6 @@
except InsufficientInventoryError as e:
sentry_sdk.capture_exception(e)
return jsonify({
"error": "InsufficientInventory",
"message": str(e),
"message": "The requested product is out of stock.",
"product_id": e.product_id
@@ -105,3 +106,4 @@
except ValueError as e:
return jsonify({"error": "BadRequest", "message": str(e)}), 400 # Use 400 Bad Request
sentry_sdk.capture_exception(e)
return jsonify({"error": "BadRequest", "message": "Invalid request data."}), 400 # Use 400 Bad Request
except Exception as e:
@@ -109,2 +111,3 @@
sentry_sdk.capture_exception(e)
sentry_sdk.capture_exception(e)
return jsonify({"error": "InternalServerError", "message": "An unexpected error occurred."}), 500
Copilot is powered by AI and may make mistakes. Always verify output.
except ValueError as e:
return jsonify({"error": "BadRequest", "message": str(e)}), 400 # Use 400 Bad Request

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 16 days ago

To fix the issue, we will replace the direct exposure of the exception message (str(e)) with a more generic error message. The specific details of the error will be logged using sentry_sdk.capture_exception(e) for debugging purposes, but the user will only see a sanitized response. This ensures that no sensitive information is leaked while still allowing developers to diagnose issues.

Changes to be made:

  1. Modify the except ValueError block (lines 105-106) to log the exception using sentry_sdk.capture_exception(e) and return a generic error message to the user.
  2. Ensure that the response to the user does not include the raw exception message.

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
@@ -105,3 +105,4 @@
     except ValueError as e:
-        return jsonify({"error": "BadRequest", "message": str(e)}), 400  # Use 400 Bad Request
+        sentry_sdk.capture_exception(e)
+        return jsonify({"error": "BadRequest", "message": "Invalid input provided."}), 400  # Use 400 Bad Request
     except Exception as e:
EOF
@@ -105,3 +105,4 @@
except ValueError as e:
return jsonify({"error": "BadRequest", "message": str(e)}), 400 # Use 400 Bad Request
sentry_sdk.capture_exception(e)
return jsonify({"error": "BadRequest", "message": "Invalid input provided."}), 400 # Use 400 Bad Request
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