-
Notifications
You must be signed in to change notification settings - Fork 30
Add Simple error handler #25
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,63 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import logging | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from fastapi import Request,HTTPException,status, UploadFile | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from fastapi.responses import JSONResponse | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from sqlalchemy.orm import Session | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from PIL import Image, UnidentifiedImageError | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import io | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import re | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger = logging.getLogger(__name__) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logging.basicConfig(level=logging.INFO, format="%(levelname)s-%(message)s") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def validate_email(email: str): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| email_regex = r'^[\w\.-]+@[\w\.-]+\.\w+$' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not re.match(email_regex, email): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise HTTPException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| detail="write your email correctly" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def check_email_exists(email: str, db: Session): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_user = db.query(User).filter(User.email == email).first() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if existing_user: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise HTTPException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status_code=status.HTTP_400_BAD_REQUEST, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| detail="Email address already exists." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+23
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainCritical: Missing User model import. The Add the import at the top of the file. For example: from app.models import User # Adjust the import path based on your project structurePlease verify the correct import path for the User model in your project and add it to the imports section. Run the following script to locate the User model definition: 🏁 Script executed: #!/bin/bash
# Description: Find the User model definition to determine the correct import path
ast-grep --pattern $'class User($$$):
$$$'Length of output: 0 🏁 Script executed: #!/bin/bash
# Check actual imports and User references in errorHandler.py
echo "=== Checking imports in errorHandler.py ==="
rg -n -B5 -A10 "def check_email_exists" model-lab/utils/errorHandler.py || echo "File or pattern not found"
echo -e "\n=== Checking all imports at top of errorHandler.py ==="
head -50 model-lab/utils/errorHandler.py || echo "File not found"
echo -e "\n=== Searching for User model definition (broader patterns) ==="
rg -n "class User" --type py || echo "No class User found"
echo -e "\n=== Searching for User imports ==="
rg -n "from.*User|import.*User" --type py -C2 || echo "No User imports found"
echo -e "\n=== Checking if User is defined in __init__.py or models ==="
find . -name "models.py" -o -name "__init__.py" | head -20Length of output: 2493 Critical: Missing User model import. The Add the import at the top of the file: from app.models import User # Adjust the import path based on your project structureVerify the correct import path for the User model in your project and update accordingly. 🧰 Tools🪛 Ruff (0.14.5)24-24: Undefined name (F821) 24-24: Undefined name (F821) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def model_load_error(req:Request, excp:Exception): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_msg=f'model loading error {req.url}:{excp}' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.error(err_msg) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return JSONResponse( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status_code=500, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={"detail":"Model Loading error,please try again after some time"} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def validate_image_file(file: UploadFile) -> Image.Image: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not file.filename.lower().endswith(('.png', '.jpg', '.jpeg')): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise HTTPException(status_code=415, detail="Unsupported image format.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| image_bytes = file.file.read() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| image = Image.open(io.BytesIO(image_bytes)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| image.verify() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| image = Image.open(io.BytesIO(image_bytes)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return image | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except UnidentifiedImageError: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.error(f"Corrupt or unreadable image file: {file.filename}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise HTTPException(status_code=400, detail="Uploaded image is corrupt or unreadable.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+40
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix file pointer handling and improve exception handling. The function has several issues:
Apply this diff to fix these issues: def validate_image_file(file: UploadFile) -> Image.Image:
try:
if not file.filename.lower().endswith(('.png', '.jpg', '.jpeg')):
raise HTTPException(status_code=415, detail="Unsupported image format.")
image_bytes = file.file.read()
+ file.file.seek(0) # Reset file pointer for potential reuse
image = Image.open(io.BytesIO(image_bytes))
image.verify()
image = Image.open(io.BytesIO(image_bytes))
return image
except UnidentifiedImageError:
- logger.error(f"Corrupt or unreadable image file: {file.filename}")
- raise HTTPException(status_code=400, detail="Uploaded image is corrupt or unreadable.")
+ logger.exception(f"Corrupt or unreadable image file: {file.filename}")
+ raise HTTPException(status_code=400, detail="Uploaded image is corrupt or unreadable.") from None📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.14.5)51-51: Consider moving this statement to an (TRY300) 54-54: Use Replace with (TRY400) 55-55: Within an (B904) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def UnhandledError(req:Request,excp:Exception ): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_msg=f'Unhandled error for request {req.url}:{excp}' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logging.error(err_msg) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return JSONResponse( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status_code=500, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={"detail":"An Internal server error,please try again after some time"} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+57
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix naming convention and logging inconsistency. The function has two issues:
Apply this diff to fix these issues: -async def UnhandledError(req:Request,excp:Exception ):
+async def unhandled_error(req: Request, excp: Exception):
err_msg=f'Unhandled error for request {req.url}:{excp}'
- logging.error(err_msg)
+ logger.error(err_msg)
return JSONResponse(
status_code=500,
content={"detail":"An Internal server error,please try again after some time"}
)Note: If you rename this function, remember to update the import in
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify usage of imported error handlers and consider refactoring existing validation.
The error handlers are imported but not used in the provided code. Additionally, the
/predictendpoint (lines 30-36) already has image validation logic that could be replaced with the newvalidate_image_filefunction to avoid duplication./predictendpoint to usevalidate_image_filefor consistency.Run the following script to check if the imported functions are used:
🏁 Script executed:
Length of output: 900
Length of output: 1532
🏁 Script executed:
Length of output: 1633
Remove unused imports from line 11.
The verification confirms that none of the imported functions are used in main.py:
validate_email,check_email_exists,model_load_error,validate_image_file, andUnhandledErrorall appear only in the import statement with no subsequent calls or registrations. Additionally, the/predictendpoint uses inlineHTTPExceptionfor image validation instead of thevalidate_image_filefunction, creating unnecessary duplication.Remove the unused import statement on line 11.
🤖 Prompt for AI Agents