ZhuLinsen/daily_stock_analysis · warning · HTTPException
file_too_large
file_too_large
Error message
图片超过 {MAX_SIZE_BYTES // (1024 * 1024)}MB 限制 What it means
Raised by /extract-from-image when the uploaded image exceeds MAX_SIZE_BYTES (5MB per the route description). The handler reads exactly MAX_SIZE_BYTES, then probes one more byte; any extra byte proves the file is larger, so oversized files are rejected without loading them fully. HTTP 400 with error code file_too_large.
Source
Thrown at api/v1/endpoints/stocks.py:161
status_code=400,
detail={"error": "bad_request", "message": "未提供文件,请使用表单字段 file 上传图片"},
)
content_type = (file.content_type or "").split(";")[0].strip().lower()
if content_type not in ALLOWED_MIME:
raise HTTPException(
status_code=400,
detail={
"error": "unsupported_type",
"message": f"不支持的类型: {content_type}。允许: {ALLOWED_MIME_STR}",
},
)
try:
# 先读取限定大小,再检查是否还有剩余(语义清晰:超出则拒绝)
data = file.file.read(MAX_SIZE_BYTES)
if file.file.read(1):
raise HTTPException(
status_code=400,
detail={
"error": "file_too_large",
"message": f"图片超过 {MAX_SIZE_BYTES // (1024 * 1024)}MB 限制",
},
)
except HTTPException:
raise
except Exception as e:
logger.warning(f"读取上传文件失败: {e}")
raise HTTPException(
status_code=400,
detail={"error": "read_failed", "message": "读取上传文件失败"},
)
try:
items, raw_text = extract_stock_codes_from_image(data, content_type)
extract_items = [View on GitHub (pinned to 5159bd72e8)
Solutions
- Compress or downscale the image client-side before upload (canvas resize or toBlob with quality ~0.8 JPEG).
- Enforce the same 5MB limit in the UI and show the size before submit.
- For PNG screenshots, convert to JPEG/WebP which typically shrinks well below 5MB.
Example fix
// before
fd.append('file', originalFile);
// after
async function shrink(file, maxBytes = 5 * 1024 * 1024) {
if (file.size <= maxBytes) return file;
const img = await createImageBitmap(file);
const scale = Math.sqrt(maxBytes / file.size) * 0.95;
const canvas = new OffscreenCanvas(Math.round(img.width * scale), Math.round(img.height * scale));
canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
return canvas.convertToBlob({type: 'image/jpeg', quality: 0.85});
}
fd.append('file', await shrink(originalFile)); Defensive patterns
Strategy: validation
Validate before calling
const MAX = 5 * 1024 * 1024;
if (file.size > MAX) {
showError(`图片超过 5MB 限制(当前 ${(file.size / 1048576).toFixed(1)}MB)`);
return;
} Type guard
function isWithinImageLimit(file: File, max = 5 * 1024 * 1024): boolean {
return file.size <= max;
} Prevention
- Check file.size before upload; downscale/compress when over the limit.
- Show the size in the UI after selection.
- Prefer JPEG/WebP for screenshots to stay well under 5MB.
When it happens
Trigger: POSTing an image >5MB; images between exactly 5MB and 5MB+1 byte (the boundary is inclusive: a file of exactly MAX_SIZE_BYTES passes); screenshots from retina displays saved as lossless PNG.
Common situations: Long trading screenshots concatenated into one tall PNG; scanned broker statements; users on mobile uploading original camera photos; GIFs with many frames.
Related errors
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/005933a8d20ea3f1.
Report an issue: GitHub.