Rthur2003 commited on
Commit
be8f2ab
·
1 Parent(s): e8b1db1

fix: standardize error response format and update request payload keys in commend endpoints

Browse files
app/routes/commend/router.py CHANGED
@@ -133,7 +133,7 @@ def _check_rate_limit(client_ip: str) -> None:
133
  if len(_rate_limit_store[client_ip]) >= _RATE_LIMIT_MAX:
134
  raise HTTPException(
135
  status_code=status.HTTP_429_TOO_MANY_REQUESTS,
136
- detail="Rate limit exceeded. Please wait before making more requests."
137
  )
138
  _rate_limit_store[client_ip].append(now)
139
 
@@ -150,7 +150,7 @@ async def _require_api_key(
150
  logger.warning(f"Unauthorized commend request from {request.client.host if request.client else 'unknown'}")
151
  raise HTTPException(
152
  status_code=status.HTTP_401_UNAUTHORIZED,
153
- detail="Invalid or missing API key."
154
  )
155
  _check_rate_limit(request.client.host if request.client else "unknown")
156
 
@@ -187,7 +187,7 @@ async def get_video_info(request: GenerateCommentRequest):
187
  if error:
188
  raise HTTPException(
189
  status_code=status.HTTP_400_BAD_REQUEST,
190
- detail=error
191
  )
192
 
193
  # Optionally fetch channel subscriber count
@@ -214,7 +214,7 @@ async def generate_youtube_comment(request: GenerateCommentRequest):
214
  logger.warning(f"Video details error: {error}")
215
  raise HTTPException(
216
  status_code=status.HTTP_400_BAD_REQUEST,
217
- detail=f"Could not fetch video details: {error}"
218
  )
219
 
220
  # 2. Skip channel stats - not critical, saves 1 API call
@@ -246,7 +246,7 @@ async def generate_youtube_comment(request: GenerateCommentRequest):
246
  logger.error(f"Comment generation failed: {gen_error}")
247
  raise HTTPException(
248
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
249
- detail=f"Comment generation failed: {gen_error}"
250
  )
251
 
252
  processing_time = time.time() - start_time
@@ -273,7 +273,7 @@ async def post_comment_to_youtube(request: PostCommentRequest):
273
  if not _COMMEND_POSTING_ENABLED:
274
  raise HTTPException(
275
  status_code=status.HTTP_403_FORBIDDEN,
276
- detail="Comment posting is disabled. Set COMMEND_ENABLE_POSTING=true to enable."
277
  )
278
 
279
  video_id = extract_video_id(request.videoUrl)
@@ -285,6 +285,7 @@ async def post_comment_to_youtube(request: PostCommentRequest):
285
  raise HTTPException(
286
  status_code=status.HTTP_409_CONFLICT,
287
  detail={
 
288
  "message": "Bu videoya zaten yorum yapılmış / Already commented on this video",
289
  "alreadyCommented": True,
290
  "previousCommentId": comment_info.get('comment_id') if comment_info else None,
@@ -299,7 +300,7 @@ async def post_comment_to_youtube(request: PostCommentRequest):
299
  logger.error(f"Comment posting failed: {error}")
300
  raise HTTPException(
301
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
302
- detail=error
303
  )
304
 
305
  # Mark video as commented (for duplicate prevention)
 
133
  if len(_rate_limit_store[client_ip]) >= _RATE_LIMIT_MAX:
134
  raise HTTPException(
135
  status_code=status.HTTP_429_TOO_MANY_REQUESTS,
136
+ detail={"code": "rate_limit_exceeded", "message": "Rate limit exceeded. Please wait before making more requests."}
137
  )
138
  _rate_limit_store[client_ip].append(now)
139
 
 
150
  logger.warning(f"Unauthorized commend request from {request.client.host if request.client else 'unknown'}")
151
  raise HTTPException(
152
  status_code=status.HTTP_401_UNAUTHORIZED,
153
+ detail={"code": "unauthorized", "message": "Invalid or missing API key."}
154
  )
155
  _check_rate_limit(request.client.host if request.client else "unknown")
156
 
 
187
  if error:
188
  raise HTTPException(
189
  status_code=status.HTTP_400_BAD_REQUEST,
190
+ detail={"code": "video_details_failed", "message": str(error)}
191
  )
192
 
193
  # Optionally fetch channel subscriber count
 
214
  logger.warning(f"Video details error: {error}")
215
  raise HTTPException(
216
  status_code=status.HTTP_400_BAD_REQUEST,
217
+ detail={"code": "video_details_failed", "message": f"Could not fetch video details: {error}"}
218
  )
219
 
220
  # 2. Skip channel stats - not critical, saves 1 API call
 
246
  logger.error(f"Comment generation failed: {gen_error}")
247
  raise HTTPException(
248
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
249
+ detail={"code": "generation_failed", "message": f"Comment generation failed: {gen_error}"}
250
  )
251
 
252
  processing_time = time.time() - start_time
 
273
  if not _COMMEND_POSTING_ENABLED:
274
  raise HTTPException(
275
  status_code=status.HTTP_403_FORBIDDEN,
276
+ detail={"code": "posting_disabled", "message": "Comment posting is disabled. Set COMMEND_ENABLE_POSTING=true to enable."}
277
  )
278
 
279
  video_id = extract_video_id(request.videoUrl)
 
285
  raise HTTPException(
286
  status_code=status.HTTP_409_CONFLICT,
287
  detail={
288
+ "code": "already_commented",
289
  "message": "Bu videoya zaten yorum yapılmış / Already commented on this video",
290
  "alreadyCommented": True,
291
  "previousCommentId": comment_info.get('comment_id') if comment_info else None,
 
300
  logger.error(f"Comment posting failed: {error}")
301
  raise HTTPException(
302
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
303
+ detail={"code": "posting_failed", "message": str(error)}
304
  )
305
 
306
  # Mark video as commented (for duplicate prevention)
tests/test_commend.py CHANGED
@@ -29,11 +29,12 @@ def test_commend_generate_rejects_invalid_url(client: TestClient) -> None:
29
  response = client.post(
30
  "/api/commend/generate",
31
  json={
32
- "url": "https://example.com",
33
- "language": "en",
34
- "style": "supportive",
35
  },
36
  )
 
37
  assert response.status_code in (400, 401, 422)
38
 
39
 
@@ -42,12 +43,13 @@ def test_commend_generate_rejects_empty_url(client: TestClient) -> None:
42
  response = client.post(
43
  "/api/commend/generate",
44
  json={
45
- "url": "",
46
- "language": "en",
47
- "style": "supportive",
48
  },
49
  )
50
- assert response.status_code in (400, 401, 422)
 
51
 
52
 
53
  def test_commend_post_disabled_by_default(client: TestClient) -> None:
@@ -55,9 +57,26 @@ def test_commend_post_disabled_by_default(client: TestClient) -> None:
55
  response = client.post(
56
  "/api/commend/post",
57
  json={
58
- "videoId": "dQw4w9WgXcQ",
59
- "comment": "Test comment",
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  },
61
  )
62
- # Either 401 (auth) or 403 (feature flag disabled)
63
- assert response.status_code in (401, 403, 422)
 
 
 
 
 
29
  response = client.post(
30
  "/api/commend/generate",
31
  json={
32
+ "videoUrl": "https://example.com",
33
+ "language": "English",
34
+ "commentStyle": "supportive",
35
  },
36
  )
37
+ # 400 (invalid url) or 401 (auth required) or 422 (validation)
38
  assert response.status_code in (400, 401, 422)
39
 
40
 
 
43
  response = client.post(
44
  "/api/commend/generate",
45
  json={
46
+ "videoUrl": "",
47
+ "language": "English",
48
+ "commentStyle": "supportive",
49
  },
50
  )
51
+ # 422 (Pydantic min_length) or 401 (auth required)
52
+ assert response.status_code in (401, 422)
53
 
54
 
55
  def test_commend_post_disabled_by_default(client: TestClient) -> None:
 
57
  response = client.post(
58
  "/api/commend/post",
59
  json={
60
+ "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
61
+ "commentText": "Test comment",
62
+ },
63
+ )
64
+ # 401 (auth required) or 403 (feature flag disabled)
65
+ assert response.status_code in (401, 403)
66
+
67
+
68
+ def test_commend_post_error_envelope_format(client: TestClient) -> None:
69
+ """Error responses should use {code, message} envelope format."""
70
+ response = client.post(
71
+ "/api/commend/post",
72
+ json={
73
+ "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
74
+ "commentText": "Test comment",
75
  },
76
  )
77
+ if response.status_code in (401, 403):
78
+ data = response.json()
79
+ detail = data.get("detail", {})
80
+ if isinstance(detail, dict):
81
+ assert "code" in detail
82
+ assert "message" in detail