fix(backend/store): improve store exception hierarchy for proper HTTP status codes (#11176)

## Summary

Fix store exception hierarchy to prevent ERROR level stack trace spam
for expected business logic errors and ensure proper HTTP status codes.

## Problem

The original error from production logs showed AgentNotFoundError for
non-existent agents like autogpt/domain-drop-catcher was:
- Returning 500 status codes instead of 404 
- Generating ERROR level stack traces in logs for expected not found
scenarios
- Bypassing global exception handlers due to improper inheritance

## Root Cause

Store exceptions inherited from Exception instead of ValueError, causing
them to bypass the global ValueError handler (400) and fall through to
the generic Exception handler (500) with full stack traces.

## Solution

Create proper exception hierarchy for ALL store-related errors by
making:
- MediaUploadError inherit from ValueError instead of Exception
- StoreError inherit from ValueError instead of Exception  
- Store NotFound exceptions inherit from NotFoundError (which inherits
from ValueError)

## Changes Made

1. MediaUploadError: Changed from Exception to ValueError inheritance
2. StoreError: Changed from Exception to ValueError inheritance  
3. Store NotFound exceptions: Changed to inherit from NotFoundError

## Benefits

- Correct HTTP status codes: Not found errors return 404, validation
errors return 400
- No more 500 stack trace spam for expected business logic errors
- Clean consistent error handling using existing global handlers
- Future-proof: Any new store exceptions automatically get proper status
codes

## Result

- AgentNotFoundError for autogpt/domain-drop-catcher now returns 404
instead of 500
- InvalidFileTypeError, VirusDetectedError, etc. now return 400 instead
of 500
- No ERROR level stack traces for expected client errors
- Proper HTTP semantics throughout the store API
This commit is contained in:
Zamil Majdy
2025-10-16 11:36:49 +07:00
committed by GitHub
parent ba53cb78dc
commit 12b1067017

View File

@@ -1,4 +1,7 @@
class MediaUploadError(Exception):
from backend.util.exceptions import NotFoundError
class MediaUploadError(ValueError):
"""Base exception for media upload errors"""
pass
@@ -48,19 +51,19 @@ class VirusScanError(MediaUploadError):
pass
class StoreError(Exception):
class StoreError(ValueError):
"""Base exception for store-related errors"""
pass
class AgentNotFoundError(StoreError):
class AgentNotFoundError(NotFoundError):
"""Raised when an agent is not found"""
pass
class CreatorNotFoundError(StoreError):
class CreatorNotFoundError(NotFoundError):
"""Raised when a creator is not found"""
pass
@@ -78,19 +81,19 @@ class DatabaseError(StoreError):
pass
class ProfileNotFoundError(StoreError):
class ProfileNotFoundError(NotFoundError):
"""Raised when a profile is not found"""
pass
class ListingNotFoundError(StoreError):
class ListingNotFoundError(NotFoundError):
"""Raised when a store listing is not found"""
pass
class SubmissionNotFoundError(StoreError):
class SubmissionNotFoundError(NotFoundError):
"""Raised when a submission is not found"""
pass