fix: handle NoSuchKey when image_features.pkl is missing in S3#17
fix: handle NoSuchKey when image_features.pkl is missing in S3#17NJX-njx wants to merge 1 commit intoorcasecurity-research:mainfrom
Conversation
…rcasecurity-research#14) - Add ClientError exception handling for s3.get_object() in product_lookup - Return user-friendly 503 error when image_features.pkl does not exist - Prevents 500 debug traceback exposure when image preprocessing not run Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
Fixes a production error path in product_lookup when the S3 artifact image_features.pkl hasn’t been generated/uploaded yet, preventing an unhandled S3 exception from surfacing as a 500 with a Werkzeug debugger page.
Changes:
- Catch
botocore.exceptions.ClientErrorarounds3.get_object()forimage_features.pkl. - When the S3 error code is
NoSuchKey, return a user-friendly JSON response with HTTP 503 and log guidance to run the preprocessing pipeline. - Add the
ClientErrorimport needed for the new exception handling.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'pipeline in the SageMaker notebook first. See README for setup instructions.' | ||
| ) | ||
| }), 503 | ||
| raise |
There was a problem hiding this comment.
The bare raise will propagate any non-NoSuchKey ClientError back to Flask; with debug=True in this app, that can still result in a Werkzeug debugger traceback being returned to end users. Consider returning a sanitized JSON error response for other S3 ClientError cases as well (and logging details server-side) instead of re-raising.
| raise | |
| app.logger.exception( | |
| "Error retrieving features file '%s' from S3 bucket '%s'", | |
| features_file_key, | |
| bucket_name, | |
| ) | |
| return jsonify({ | |
| 'error': 'Unable to retrieve image features from storage. Please try again later.' | |
| }), 500 |
| app.logger.error( | ||
| 'image_features.pkl not found in S3 bucket %s. ' | ||
| 'Please run the image preprocessing pipeline in the SageMaker notebook first.', | ||
| bucket_name |
There was a problem hiding this comment.
This log line drops the actual S3 error details (code/message/request-id), which can make debugging harder. Consider including e.response['Error'] fields (or logging with exc_info=True) while still returning a user-friendly response to the client.
| app.logger.error( | |
| 'image_features.pkl not found in S3 bucket %s. ' | |
| 'Please run the image preprocessing pipeline in the SageMaker notebook first.', | |
| bucket_name | |
| error_info = e.response.get('Error', {}) | |
| request_id = e.response.get('ResponseMetadata', {}).get('RequestId') | |
| app.logger.error( | |
| 'image_features.pkl not found in S3 bucket %s. ' | |
| 'Please run the image preprocessing pipeline in the SageMaker notebook first. ' | |
| 'S3 error code=%s, message=%s, request_id=%s', | |
| bucket_name, | |
| error_info.get('Code'), | |
| error_info.get('Message'), | |
| request_id, |
Summary
Fixes #14
When users upload a photo for analysis without having run the image preprocessing pipeline in the SageMaker notebook, \image_features.pkl\ does not exist in S3. The backend previously threw an unhandled \NoSuchKey\ exception, resulting in a 500 error with the full Werkzeug debug traceback (including sensitive debug info).
Changes
Testing
No AWS deployment required - the change is a straightforward exception handler that returns a JSON error response instead of propagating the exception.
Made with Cursor