From 64dab184285d94b9c6c5c0a922cb526b5c551733 Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Sat, 4 Apr 2026 08:49:01 -0400 Subject: [PATCH] Clean up presigned URL implementation: remove dead fields, fix error handling - Remove unused image_url from upload response and TS type - Remove bare except in serve_image that masked config errors as 404s - Add error state and broken-image placeholder in QuestionBubble Co-Authored-By: Claude Opus 4.6 --- blueprints/conversation/__init__.py | 13 ++----------- raggr-frontend/src/api/conversationService.ts | 2 +- raggr-frontend/src/components/QuestionBubble.tsx | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/blueprints/conversation/__init__.py b/blueprints/conversation/__init__.py index 2ebc915..4175eff 100644 --- a/blueprints/conversation/__init__.py +++ b/blueprints/conversation/__init__.py @@ -123,22 +123,13 @@ async def upload_image(): await s3_upload_image(processed_bytes, key, output_content_type) - return jsonify( - { - "image_key": key, - "image_url": f"/api/conversation/image/{key}", - } - ) + return jsonify({"image_key": key}) @conversation_blueprint.get("/image/") @jwt_refresh_token_required async def serve_image(image_key: str): - try: - url = await s3_presigned_url(image_key) - except Exception: - return jsonify({"error": "Image not found"}), 404 - + url = await s3_presigned_url(image_key) return jsonify({"url": url}) diff --git a/raggr-frontend/src/api/conversationService.ts b/raggr-frontend/src/api/conversationService.ts index 1135058..efd4b58 100644 --- a/raggr-frontend/src/api/conversationService.ts +++ b/raggr-frontend/src/api/conversationService.ts @@ -125,7 +125,7 @@ class ConversationService { async uploadImage( file: File, conversationId: string, - ): Promise<{ image_key: string; image_url: string }> { + ): Promise<{ image_key: string }> { const formData = new FormData(); formData.append("file", file); formData.append("conversation_id", conversationId); diff --git a/raggr-frontend/src/components/QuestionBubble.tsx b/raggr-frontend/src/components/QuestionBubble.tsx index 081c726..a3678e4 100644 --- a/raggr-frontend/src/components/QuestionBubble.tsx +++ b/raggr-frontend/src/components/QuestionBubble.tsx @@ -9,10 +9,17 @@ type QuestionBubbleProps = { export const QuestionBubble = ({ text, image_key }: QuestionBubbleProps) => { const [imageUrl, setImageUrl] = useState(null); + const [imageError, setImageError] = useState(false); useEffect(() => { if (!image_key) return; - conversationService.getPresignedImageUrl(image_key).then(setImageUrl).catch(() => {}); + conversationService + .getPresignedImageUrl(image_key) + .then(setImageUrl) + .catch((err) => { + console.error("Failed to load image:", err); + setImageError(true); + }); }, [image_key]); return ( @@ -25,6 +32,12 @@ export const QuestionBubble = ({ text, image_key }: QuestionBubbleProps) => { "shadow-sm shadow-leaf/10", )} > + {imageError && ( +
+ 🖼️ + Image failed to load +
+ )} {imageUrl && (