Skip to content

Commit 4f571ac

Browse files
msureshkumar88Suresh Kumar Moharajancrivetimihai
authored
feat(security): Enforce Content Size Limits for resources and prompts (fixes #538 US-1) (#3251)
* feat(security): enforce content size limits for resources and prompts Implement configurable content size validation to prevent DoS attacks via oversized content submissions. Resources are limited to 100KB and prompt templates to 10KB by default (configurable via environment variables CONTENT_MAX_RESOURCE_SIZE and CONTENT_MAX_PROMPT_SIZE). Validation occurs at the service layer before database operations, returning 413 Payload Too Large with structured error details. Closes #538 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix(security): review fixes for content size limits PR - Fix ResourceCreate.validate_content to remove MAX_CONTENT_LENGTH schema-level check (now handled by service layer, consistent with ResourceUpdate) - Fix broken test assertions checking raw bytes in formatted messages (TestErrorMessageClarity was asserting "200000" in human-readable "195.3 KB" strings) - Fix broken test_update_prompt_validation_and_integrity_errors which had its body accidentally deleted by the original PR - Restore accidentally deleted assertions in test_list_resources and test_create_resource_endpoint - Add global exception handler for ContentSizeError (defense-in-depth, consistent with existing handlers for ValidationError/IntegrityError) - Add reset_content_security_service() for test isolation - Remove "Made with Bob" watermark from test file - Remove duplicate pytest import in integration tests - Fix broken README link to non-existent migration guide - Fix double-commented lines in .env.example Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix: resolve flake8 lint issues in content size limits PR - Move noqa:DUO138 to the line flake8 reports (validators.py) - Add Args/Returns to content_size_exception_handler docstring (DAR101/DAR201) Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix(tests): update security tests for service-layer size validation Content size validation moved from Pydantic schema to service layer (returns 413 instead of 422). Update test_resource_create_content_validation and test_zip_bomb_prevention to reflect that ResourceCreate no longer rejects oversized content at schema level. Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix(security): address codex review findings for content size limits 1. Remove MAX_TEMPLATE_LENGTH check from SecurityValidator.validate_template so the configurable CONTENT_MAX_PROMPT_SIZE is not silently capped at 64KB by the schema-level validator (finding #1) 2. Add db.rollback() to ContentSizeError handlers in resource_service to prevent partial metadata mutations from being committed when content size validation fails after ORM fields are already updated (finding #2) 3. Include actual_size and max_size in admin route 413 responses to match the structured error contract used by API routes (finding #3) 4. Update security and validator tests that expected schema-level length rejection — size enforcement now happens at service layer Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * chore: fix trailing whitespace in test files Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * docs: add content size limits to configuration docs, securing guide, and Helm values - docs/docs/manage/configuration.md: add Content Security section with env var table, scope note, and error response example - docs/docs/manage/securing.md: add section 9 (Content Size Limits) to production security checklist, renumber subsequent sections - charts/mcp-stack/values.yaml: add CONTENT_MAX_RESOURCE_SIZE and CONTENT_MAX_PROMPT_SIZE to gateway env config Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> --------- Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Co-authored-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
1 parent 4e89b04 commit 4f571ac

23 files changed

Lines changed: 1564 additions & 56 deletions

.env.example

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ ALLOW_PUBLIC_VISIBILITY=true
9797
# SSRF_BLOCKED_NETWORKS=["169.254.169.254/32","169.254.169.123/32","fd00::1/128","169.254.0.0/16","fe80::/10","100.64.0.0/10"]
9898
# The 100.64.0.0/10 range is Carrier-Grade NAT (CGNAT) which some cloud providers use
9999

100+
# -----------------------------------------------------------------------------
101+
# Content Security - Size Limits
102+
# -----------------------------------------------------------------------------
103+
# Maximum content sizes (in bytes) to prevent DoS attacks via large uploads
104+
105+
# Maximum size for resource content (default: 102400 = 100KB)
106+
# Resources exceeding this limit will be rejected with 413 Payload Too Large
107+
# CONTENT_MAX_RESOURCE_SIZE=102400
108+
109+
# Maximum size for prompt templates (default: 10240 = 10KB)
110+
# Prompts exceeding this limit will be rejected with 413 Payload Too Large
111+
# CONTENT_MAX_PROMPT_SIZE=10240
112+
100113
# =============================================================================
101114
# Project defaults (batteries-included overrides)
102115
# =============================================================================

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,17 @@ These settings are enabled by default for security—only disable for backward c
748748
| `REQUIRE_TOKEN_EXPIRATION` | Require exp claim in tokens | `true` |
749749
| `PUBLIC_REGISTRATION_ENABLED` | Allow public user self-registration | `false` |
750750

751+
### 🛡️ Content Security
752+
753+
Content size limits prevent DoS attacks and ensure system stability:
754+
755+
| Variable | Description | Default |
756+
|----------|-------------|---------|
757+
| `CONTENT_MAX_RESOURCE_SIZE` | Maximum resource content size (bytes) | `102400` (100KB) |
758+
| `CONTENT_MAX_PROMPT_SIZE` | Maximum prompt template size (bytes) | `10240` (10KB) |
759+
760+
**Note:** Size limits apply only to new create/update operations. Existing content is not retroactively validated.
761+
751762
### ⚙️ Project Defaults (Dev Setup)
752763

753764
These values differ from code defaults to provide a working local/dev setup:

charts/mcp-stack/values.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,12 @@ mcpContextForge:
410410
# SSRF_ALLOW_PRIVATE_NETWORKS: "false"
411411
# SSRF_ALLOWED_NETWORKS: '["10.96.0.0/12"]' # example only, adjust to your cluster CIDR
412412

413+
# ─ Content Security - Size Limits ─
414+
# Maximum content sizes (bytes) to prevent DoS via oversized uploads.
415+
# Exceeding these returns HTTP 413 Payload Too Large.
416+
CONTENT_MAX_RESOURCE_SIZE: "102400" # 100KB default (min 1KB, max 10MB)
417+
CONTENT_MAX_PROMPT_SIZE: "10240" # 10KB default (min 512B, max 1MB)
418+
413419
# ─ Logging ─
414420
LOG_LEVEL: INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
415421
LOG_FORMAT: json # json or text format

docs/docs/manage/configuration.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,31 @@ mcpContextForge:
669669
(`SSRF_ALLOW_LOCALHOST=true`, `SSRF_ALLOW_PRIVATE_NETWORKS=true`, `SSRF_DNS_FAIL_CLOSED=false`) so bundled test services can register without extra setup.
670670
Keep production deployments on strict SSRF values unless you explicitly need internal destination access.
671671

672+
### Content Security - Size Limits
673+
674+
Content size limits prevent DoS attacks and resource exhaustion from oversized content submissions. Validation occurs at the service layer before database writes and returns **HTTP 413 Payload Too Large** with structured error details.
675+
676+
| Setting | Description | Default | Range |
677+
| ---------------------------- | ------------------------------------------------ | --------- | --------------- |
678+
| `CONTENT_MAX_RESOURCE_SIZE` | Maximum resource content size (bytes) | `102400` (100KB) | 1KB – 10MB |
679+
| `CONTENT_MAX_PROMPT_SIZE` | Maximum prompt template size (bytes) | `10240` (10KB) | 512B – 1MB |
680+
681+
!!! note "Scope"
682+
Size limits apply only to new create and update operations. Existing content is not retroactively validated.
683+
684+
!!! example "Error Response"
685+
Oversized content returns a structured 413 response:
686+
```json
687+
{
688+
"detail": {
689+
"error": "Resource content size limit exceeded",
690+
"message": "Resource content size (195.3 KB) exceeds maximum allowed size (100.0 KB)",
691+
"actual_size": 200000,
692+
"max_size": 102400
693+
}
694+
}
695+
```
696+
672697
### Ed25519 Certificate Signing
673698

674699
ContextForge supports **Ed25519 digital signatures** for certificate validation and integrity verification.

docs/docs/manage/securing.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,20 @@ The CI pipeline automatically verifies SRI hashes on every build to detect unexp
425425
- [x] Hashes use SHA-384 algorithm (W3C recommended)
426426
- [ ] Review SRI hashes after any CDN library updates
427427

428-
### 9. Container Security
428+
### 9. Content Size Limits
429+
430+
Configure content size limits to prevent DoS via oversized resource or prompt submissions:
431+
432+
```bash
433+
# Defaults shown — adjust to your workload requirements
434+
CONTENT_MAX_RESOURCE_SIZE=102400 # 100KB for resources (range: 1KB–10MB)
435+
CONTENT_MAX_PROMPT_SIZE=10240 # 10KB for prompt templates (range: 512B–1MB)
436+
```
437+
438+
- [ ] Review default size limits for your use case
439+
- [ ] Monitor 413 responses in logs for legitimate content being blocked
440+
441+
### 10. Container Security
429442

430443
```bash
431444
# Run containers with security constraints
@@ -443,15 +456,15 @@ docker run \
443456
- [ ] Set resource limits (CPU, memory)
444457
- [ ] Scan images for vulnerabilities
445458

446-
### 10. Secrets Management
459+
### 11. Secrets Management
447460

448461
- [ ] **Never store secrets in environment variables directly**
449462
- [ ] Use a secrets management system (Vault, AWS Secrets Manager, etc.)
450463
- [ ] Rotate credentials regularly
451464
- [ ] Restrict container access to secrets
452465
- [ ] Never commit `.env` files to version control
453466

454-
### 11. MCP Server Validation
467+
### 12. MCP Server Validation
455468

456469
Before connecting any MCP server:
457470

@@ -461,23 +474,23 @@ Before connecting any MCP server:
461474
- [ ] Monitor server behavior for anomalies
462475
- [ ] Implement rate limiting for untrusted servers
463476

464-
### 12. Database Security
477+
### 13. Database Security
465478

466479
- [ ] Use TLS for database connections
467480
- [ ] Configure strong passwords
468481
- [ ] Restrict database access by IP/network
469482
- [ ] Enable audit logging
470483
- [ ] Regular backups with encryption
471484

472-
### 13. Monitoring & Logging
485+
### 14. Monitoring & Logging
473486

474487
- [ ] Set up structured logging without sensitive data
475488
- [ ] Configure log rotation and secure storage
476489
- [ ] Implement monitoring and alerting
477490
- [ ] Set up anomaly detection
478491
- [ ] Create incident response procedures
479492

480-
### 14. Integration Security
493+
### 15. Integration Security
481494

482495
ContextForge should be integrated with:
483496

@@ -487,7 +500,7 @@ ContextForge should be integrated with:
487500
- [ ] SIEM for security monitoring
488501
- [ ] Load balancer with TLS termination
489502

490-
### 15. Well-Known URI Security
503+
### 16. Well-Known URI Security
491504

492505
Configure well-known URIs appropriately for your deployment:
493506

@@ -511,7 +524,7 @@ Security considerations:
511524
- [ ] Update security.txt Expires field before expiration
512525
- [ ] Consider custom well-known files only if necessary
513526

514-
### 16. Downstream Application Security
527+
### 17. Downstream Application Security
515528

516529
Applications consuming ContextForge data must:
517530

mcpgateway/admin.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
from mcpgateway.services.argon2_service import Argon2PasswordService
126126
from mcpgateway.services.audit_trail_service import get_audit_trail_service
127127
from mcpgateway.services.catalog_service import catalog_service
128+
from mcpgateway.services.content_security import ContentSizeError
128129
from mcpgateway.services.email_auth_service import AuthenticationError, EmailAuthService, PasswordValidationError
129130
from mcpgateway.services.encryption_service import get_encryption_service
130131
from mcpgateway.services.export_service import ExportError, ExportService
@@ -12100,6 +12101,9 @@ async def admin_add_resource(request: Request, db: Session = Depends(get_db), us
1210012101
if isinstance(ex, ResourceURIConflictError):
1210112102
LOGGER.error(f"ResourceURIConflictError in admin_add_resource: {ex}")
1210212103
return ORJSONResponse(content={"message": str(ex), "success": False}, status_code=409)
12104+
if isinstance(ex, ContentSizeError):
12105+
LOGGER.error(f"ContentSizeError in admin_add_resource: {ex}")
12106+
return ORJSONResponse(content={"message": str(ex), "success": False, "actual_size": ex.actual_size, "max_size": ex.max_size}, status_code=413)
1210312107
LOGGER.error(f"Error in admin_add_resource: {ex}")
1210412108
return ORJSONResponse(content={"message": str(ex), "success": False}, status_code=500)
1210512109

@@ -12189,6 +12193,9 @@ async def admin_edit_resource(
1218912193
if isinstance(ex, ResourceURIConflictError):
1219012194
LOGGER.error(f"ResourceURIConflictError in admin_edit_resource: {ex}")
1219112195
return ORJSONResponse(status_code=409, content={"message": str(ex), "success": False})
12196+
if isinstance(ex, ContentSizeError):
12197+
LOGGER.error(f"ContentSizeError in admin_edit_resource: {ex}")
12198+
return ORJSONResponse(status_code=413, content={"message": str(ex), "success": False, "actual_size": ex.actual_size, "max_size": ex.max_size})
1219212199
LOGGER.error(f"Error in admin_edit_resource: {ex}")
1219312200
return ORJSONResponse(content={"message": str(ex), "success": False}, status_code=500)
1219412201

@@ -12423,6 +12430,9 @@ async def admin_add_prompt(request: Request, db: Session = Depends(get_db), user
1242312430
if isinstance(ex, PromptArgumentsJSONError):
1242412431
LOGGER.error(f"PromptArgumentsJSONError in admin_add_prompt: {ex}")
1242512432
return ORJSONResponse(status_code=422, content={"message": str(ex), "success": False, "field": ex.field_name})
12433+
if isinstance(ex, ContentSizeError):
12434+
LOGGER.error(f"ContentSizeError in admin_add_prompt: {ex}")
12435+
return ORJSONResponse(status_code=413, content={"message": str(ex), "success": False, "actual_size": ex.actual_size, "max_size": ex.max_size})
1242612436
LOGGER.error(f"Error in admin_add_prompt: {ex}")
1242712437
return ORJSONResponse(content={"message": str(ex), "success": False}, status_code=500)
1242812438

@@ -12524,6 +12534,9 @@ async def admin_edit_prompt(
1252412534
if isinstance(ex, PromptArgumentsJSONError):
1252512535
LOGGER.error(f"PromptArgumentsJSONError in admin_edit_prompt: {ex}")
1252612536
return ORJSONResponse(status_code=422, content={"message": str(ex), "success": False, "field": ex.field_name})
12537+
if isinstance(ex, ContentSizeError):
12538+
LOGGER.error(f"ContentSizeError in admin_edit_prompt: {ex}")
12539+
return ORJSONResponse(status_code=413, content={"message": str(ex), "success": False, "actual_size": ex.actual_size, "max_size": ex.max_size})
1252712540
LOGGER.error(f"Error in admin_edit_prompt: {ex}")
1252812541
return ORJSONResponse(content={"message": str(ex), "success": False}, status_code=500)
1252912542

mcpgateway/common/validators.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@
7676
_HTML_SPECIAL_CHARS_RE: Pattern[str] = re.compile(r'[<>"\']') # / removed per SEP-986
7777
_DANGEROUS_TEMPLATE_TAGS_RE: Pattern[str] = re.compile(r"<(script|iframe|object|embed|link|meta|base|form)\b", re.IGNORECASE)
7878
_EVENT_HANDLER_RE: Pattern[str] = re.compile(r"on\w+\s*=", re.IGNORECASE)
79-
_MIME_TYPE_RE: Pattern[str] = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+\.]*\/[a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+\.]*(?:\s*;\s*[a-zA-Z0-9!#$&\-\^_+\.]+=(?:[a-zA-Z0-9!#$&\-\^_+\.]+|"[^"\r\n]*"))*$') # noqa: DUO138 - no ReDoS: inner groups require literal ; and = delimiters preventing backtrack ambiguity
79+
_MIME_TYPE_RE: Pattern[str] = re.compile( # noqa: DUO138 - no ReDoS: inner groups require literal ; and = delimiters preventing backtrack ambiguity
80+
r'^[a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+\.]*\/[a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+\.]*(?:\s*;\s*[a-zA-Z0-9!#$&\-\^_+\.]+=(?:[a-zA-Z0-9!#$&\-\^_+\.]+|"[^"\r\n]*"))*$'
81+
)
8082
_URI_SCHEME_RE: Pattern[str] = re.compile(r"^[a-zA-Z][a-zA-Z0-9+\-.]*://")
8183
_SHELL_DANGEROUS_CHARS_RE: Pattern[str] = re.compile(r"[;&|`$(){}\[\]<>]")
8284
_ANSI_ESCAPE_RE: Pattern[str] = re.compile(r"\x1B\[[0-9;]*[A-Za-z]")
@@ -833,20 +835,13 @@ def validate_template(cls, value: str) -> str:
833835
...
834836
ValueError: Template contains potentially dangerous expressions
835837
836-
Length limit testing:
837-
838-
>>> long_template = 'a' * 65537
839-
>>> SecurityValidator.validate_template(long_template)
840-
Traceback (most recent call last):
841-
...
842-
ValueError: Template exceeds maximum length of 65536
838+
Length limit note: size validation is performed at the service layer
839+
using configurable limits (ContentSecurityService). This validator
840+
only checks encoding, dangerous patterns, and SSTI prevention.
843841
"""
844842
if not value:
845843
return value
846844

847-
if len(value) > cls.MAX_TEMPLATE_LENGTH:
848-
raise ValueError(f"Template exceeds maximum length of {cls.MAX_TEMPLATE_LENGTH}")
849-
850845
# Block dangerous tags but allow Jinja2 syntax {{ }} and {% %} (uses precompiled regex)
851846
if _DANGEROUS_TEMPLATE_TAGS_RE.search(value):
852847
raise ValueError("Template contains HTML tags that may interfere with proper display")

mcpgateway/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,10 @@ def parse_issuers(cls, v: Any) -> list[str]:
15571557
tool_rate_limit: int = 100 # requests per minute
15581558
tool_concurrent_limit: int = 10
15591559

1560+
# Content Security - Size Limits
1561+
content_max_resource_size: int = Field(default=102400, ge=1024, le=10485760, description="Maximum size in bytes for resource content (default: 100KB)") # 100KB # Minimum 1KB # Maximum 10MB
1562+
content_max_prompt_size: int = Field(default=10240, ge=512, le=1048576, description="Maximum size in bytes for prompt templates (default: 10KB)") # 10KB # Minimum 512 bytes # Maximum 1MB
1563+
15601564
# MCP Session Pool - reduces per-request latency from ~20ms to ~1-2ms
15611565
# Disabled by default for safety. Enable explicitly in production after testing.
15621566
mcp_session_pool_enabled: bool = False

mcpgateway/main.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
from mcpgateway.services.a2a_service import A2AAgentError, A2AAgentNameConflictError, A2AAgentNotFoundError, A2AAgentService
135135
from mcpgateway.services.cancellation_service import cancellation_service
136136
from mcpgateway.services.completion_service import CompletionService
137+
from mcpgateway.services.content_security import ContentSizeError
137138
from mcpgateway.services.email_auth_service import EmailAuthService
138139
from mcpgateway.services.export_service import ExportError, ExportService
139140
from mcpgateway.services.gateway_service import GatewayConnectionError, GatewayDuplicateConflictError, GatewayError, GatewayNameConflictError, GatewayNotFoundError
@@ -2151,6 +2152,20 @@ async def database_exception_handler(_request: Request, exc: IntegrityError):
21512152
return ORJSONResponse(status_code=409, content=ErrorFormatter.format_database_error(exc))
21522153

21532154

2155+
@app.exception_handler(ContentSizeError)
2156+
async def content_size_exception_handler(_request: Request, exc: ContentSizeError):
2157+
"""Handle content size limit violations globally.
2158+
2159+
Args:
2160+
_request: The incoming request (unused, required by FastAPI handler interface).
2161+
exc: The ContentSizeError with actual_size, max_size, and content_type.
2162+
2163+
Returns:
2164+
ORJSONResponse: A 413 Payload Too Large response with structured error details.
2165+
"""
2166+
return ORJSONResponse(status_code=413, content={"detail": {"error": f"{exc.content_type} size limit exceeded", "message": str(exc), "actual_size": exc.actual_size, "max_size": exc.max_size}})
2167+
2168+
21542169
# RFC 9110 §5.6.2 'token' pattern for header field names:
21552170
# token = 1*tchar
21562171
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
@@ -5411,6 +5426,9 @@ async def create_resource(
54115426
except IntegrityError as e:
54125427
logger.error(f"Integrity error while creating resource: {e}")
54135428
raise HTTPException(status_code=409, detail=ErrorFormatter.format_database_error(e))
5429+
except ContentSizeError as e:
5430+
logger.error(f"Content size exceeded in creating resource: {e}")
5431+
raise HTTPException(status_code=413, detail={"error": f"{e.content_type} size limit exceeded", "message": str(e), "actual_size": e.actual_size, "max_size": e.max_size})
54145432

54155433

54165434
@resource_router.get("/{resource_id}")
@@ -5591,6 +5609,9 @@ async def update_resource(
55915609
raise HTTPException(status_code=409, detail=ErrorFormatter.format_database_error(e))
55925610
except ResourceURIConflictError as e:
55935611
raise HTTPException(status_code=409, detail=str(e))
5612+
except ContentSizeError as e:
5613+
logger.error(f"Content size exceeded in updating resource: {e}")
5614+
raise HTTPException(status_code=413, detail={"error": f"{e.content_type} size limit exceeded", "message": str(e), "actual_size": e.actual_size, "max_size": e.max_size})
55945615
db.commit()
55955616
db.close()
55965617
await invalidate_resource_cache(resource_id)
@@ -5915,6 +5936,9 @@ async def create_prompt(
59155936
# If there is an integrity error, return a 409 Conflict error
59165937
logger.error(f"Integrity error while creating prompt: {e}")
59175938
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=ErrorFormatter.format_database_error(e))
5939+
if isinstance(e, ContentSizeError):
5940+
logger.error(f"Content size exceeded in creating prompt: {e}")
5941+
raise HTTPException(status_code=413, detail={"error": f"{e.content_type} size limit exceeded", "message": str(e), "actual_size": e.actual_size, "max_size": e.max_size})
59185942
# For any other unexpected errors, return a 500 Internal Server Error
59195943
logger.error(f"Unexpected error while creating prompt: {e}")
59205944
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="An unexpected error occurred while creating the prompt")
@@ -6109,6 +6133,9 @@ async def update_prompt(
61096133
if isinstance(e, PromptError):
61106134
# If there is a general prompt error, return a 400 Bad Request error
61116135
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
6136+
if isinstance(e, ContentSizeError):
6137+
logger.error(f"Content size exceeded in updating prompt: {e}")
6138+
raise HTTPException(status_code=413, detail={"error": f"{e.content_type} size limit exceeded", "message": str(e), "actual_size": e.actual_size, "max_size": e.max_size})
61126139
# For any other unexpected errors, return a 500 Internal Server Error
61136140
logger.error(f"Unexpected error while updating prompt: {e}")
61146141
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="An unexpected error occurred while updating the prompt")

0 commit comments

Comments
 (0)