Repository navigation
Conversation
mjy926
commented
Jul 13, 2026
- 채점 서버를 pecan으로 수정했습니다
- 지원하는 언어 enum 타입에 rust를 추가했습니다
📝 WalkthroughWalkthroughHODU 연동을 새 제출 API 형식에 맞게 변경하고, 언어·제출 상태 매핑과 오류 응답 모델을 갱신했습니다. Go, TypeScript, Rust 지원과 언어별 리소스 설정을 추가했으며, 데이터베이스 ENUM에도 Rust를 반영했습니다. ChangesHODU 언어 및 제출 흐름
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant HoduApiRepository
participant HODU_API
participant HoduSubmitResponse
HoduApiRepository->>HODU_API: 새 payload로 제출 요청
HODU_API-->>HoduApiRepository: 상태 및 채점 결과 JSON 반환
HoduApiRepository->>HoduSubmitResponse: 응답 필드 매핑 및 반환
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
wacruit/src/database/migrations/versions/2026_07_13_1036-e57751b758ee_.py (1)
58-93: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winDowngrade 시 RUST 데이터가 존재하면 실패합니다.
downgrade()에서 ENUM에서RUST값을 제거하지만, 이미language='RUST'인 제출 레코드가 존재하는 경우 MySQLALTER TABLE이 거부됩니다. 개발/스테이징 환경에서는 일반적으로 허용되는 패턴이지만, 프로덕션에서 downgrade가 필요한 시나리오라면 RUST 제출 데이터를 미리 정리하는 단계가 필요합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@wacruit/src/database/migrations/versions/2026_07_13_1036-e57751b758ee_.py` around lines 58 - 93, Update downgrade() before the code_submission.language ENUM alteration to handle existing rows with language='RUST' by applying the project’s intended cleanup or conversion strategy, then perform the ENUM change so the downgrade succeeds when RUST data exists.wacruit/src/apps/hodu/schemas.py (1)
65-81: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
to_submission_result_status에도 멤버십 체크 추가 권장.
from_submission_result_status는 매핑에 없는 값이면 명확한ValueError를 던지도록 방어 코드가 있는 반면,to_submission_result_status는mapping[self]로 직접 접근합니다. 현재는 7개 상태값이 모두 매핑돼 있어 문제가 없지만, 두 메서드의 방어 수준을 동일하게 맞추면 향후 상태값 추가 시 불명확한KeyError대신 명확한 예외를 얻을 수 있습니다.♻️ 제안
def to_submission_result_status(self) -> CodeSubmissionResultStatus: mapping = { HoduSubmitStatus.CORRECT: CodeSubmissionResultStatus.CORRECT, HoduSubmitStatus.WRONG: CodeSubmissionResultStatus.WRONG, HoduSubmitStatus.COMPILE_ERROR: CodeSubmissionResultStatus.COMPILE_ERROR, HoduSubmitStatus.RUNTIME_ERROR: CodeSubmissionResultStatus.RUNTIME_ERROR, HoduSubmitStatus.TIME_LIMIT_EXCEEDED: ( CodeSubmissionResultStatus.TIME_LIMIT_EXCEEDED ), HoduSubmitStatus.MEMORY_LIMIT_EXCEEDED: ( CodeSubmissionResultStatus.MEMORY_LIMIT_EXCEEDED ), HoduSubmitStatus.INTERNAL_ERROR: ( CodeSubmissionResultStatus.INTERNAL_SERVER_ERROR ), } - return mapping[self] + if self in mapping: + return mapping[self] + raise ValueError(f"Invalid HoduSubmitStatus: {self}")🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@wacruit/src/apps/hodu/schemas.py` around lines 65 - 81, Update HoduSubmitStatus.to_submission_result_status to validate membership before retrieving the mapped value, matching the defensive behavior of from_submission_result_status. For unmapped status values, raise the same clear ValueError style used by from_submission_result_status instead of allowing mapping[self] to produce a KeyError; preserve the existing mappings for supported statuses.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@wacruit/src/apps/hodu/repositories.py`:
- Around line 47-74: Update the Hodu API error-response handling in the visible
submission method to parse the response body only once and reuse that value for
both logging and detail extraction. Catch the JSON decoding failure alongside
the existing ValidationError handling, and return the established
HoduSubmitErrorResponse with a safe fallback detail when a 4xx/5xx response is
not valid JSON.
---
Nitpick comments:
In `@wacruit/src/apps/hodu/schemas.py`:
- Around line 65-81: Update HoduSubmitStatus.to_submission_result_status to
validate membership before retrieving the mapped value, matching the defensive
behavior of from_submission_result_status. For unmapped status values, raise the
same clear ValueError style used by from_submission_result_status instead of
allowing mapping[self] to produce a KeyError; preserve the existing mappings for
supported statuses.
In `@wacruit/src/database/migrations/versions/2026_07_13_1036-e57751b758ee_.py`:
- Around line 58-93: Update downgrade() before the code_submission.language ENUM
alteration to handle existing rows with language='RUST' by applying the
project’s intended cleanup or conversion strategy, then perform the ENUM change
so the downgrade succeeds when RUST data exists.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 21cbd90e-d622-45ff-ac8a-ac876dec4747
📒 Files selected for processing (7)
.env.testwacruit/src/apps/common/enums.pywacruit/src/apps/hodu/config.pywacruit/src/apps/hodu/repositories.pywacruit/src/apps/hodu/schemas.pywacruit/src/apps/problem/utils_v2.pywacruit/src/database/migrations/versions/2026_07_13_1036-e57751b758ee_.py
💤 Files with no reviewable changes (1)
- wacruit/src/apps/hodu/config.py
| if response.status_code >= HTTPStatus.BAD_REQUEST: | ||
| self.logger.error( | ||
| "HODU API ERROR for sending %s / status code: %d / response: %s", | ||
| response.url, | ||
| response.status_code, | ||
| response.json(), | ||
| ) | ||
| return HoduSubmitErrorResponse(**response.json()) | ||
| return HoduSubmitResponse(**response.json()) | ||
| data = response.json() | ||
| detail = ( | ||
| data.get("InternalError") | ||
| or data.get("ServiceBusy") | ||
| or "Unknown error" | ||
| ) | ||
| return HoduSubmitErrorResponse(detail=detail) | ||
|
|
||
| raw_data = response.json() | ||
| mapped_data = { | ||
| "status": raw_data.get("status"), | ||
| "fields": { | ||
| "time": raw_data.get("time"), | ||
| "memory": int(raw_data["memory"]) | ||
| if raw_data.get("memory") is not None | ||
| else None, | ||
| "stdout": raw_data.get("stdout"), | ||
| "stderr": raw_data.get("stderr"), | ||
| }, | ||
| } | ||
| return HoduSubmitResponse(**mapped_data) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
비-JSON 에러 응답 시 예외가 처리되지 않음.
except ValidationError만 캐치하므로, Hodu API가 4xx/5xx에서 JSON이 아닌 본문(예: 게이트웨이 에러 페이지)을 반환하면 response.json() 호출이 JSONDecodeError를 던지고 이 예외는 그대로 전파됩니다. 외부 API 호출 실패를 다루는 코드에서 이런 처리되지 않은 파싱 예외는 재시도만 반복하다 원인 불명의 에러로 실패하게 됩니다. 또한 에러 분기에서 response.json()을 두 번(로그, data 할당) 호출하는 것도 불필요한 중복입니다.
🛡️ 제안: JSON 파싱을 한 번만 수행하고 디코딩 오류도 처리
try:
if response.status_code >= HTTPStatus.BAD_REQUEST:
+ try:
+ data = response.json()
+ except ValueError:
+ data = {}
self.logger.error(
"HODU API ERROR for sending %s / status code: %d / response: %s",
response.url,
response.status_code,
- response.json(),
+ data,
)
- data = response.json()
detail = (
data.get("InternalError")
or data.get("ServiceBusy")
or "Unknown error"
)
return HoduSubmitErrorResponse(detail=detail)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if response.status_code >= HTTPStatus.BAD_REQUEST: | |
| self.logger.error( | |
| "HODU API ERROR for sending %s / status code: %d / response: %s", | |
| response.url, | |
| response.status_code, | |
| response.json(), | |
| ) | |
| return HoduSubmitErrorResponse(**response.json()) | |
| return HoduSubmitResponse(**response.json()) | |
| data = response.json() | |
| detail = ( | |
| data.get("InternalError") | |
| or data.get("ServiceBusy") | |
| or "Unknown error" | |
| ) | |
| return HoduSubmitErrorResponse(detail=detail) | |
| raw_data = response.json() | |
| mapped_data = { | |
| "status": raw_data.get("status"), | |
| "fields": { | |
| "time": raw_data.get("time"), | |
| "memory": int(raw_data["memory"]) | |
| if raw_data.get("memory") is not None | |
| else None, | |
| "stdout": raw_data.get("stdout"), | |
| "stderr": raw_data.get("stderr"), | |
| }, | |
| } | |
| return HoduSubmitResponse(**mapped_data) | |
| if response.status_code >= HTTPStatus.BAD_REQUEST: | |
| try: | |
| data = response.json() | |
| except ValueError: | |
| data = {} | |
| self.logger.error( | |
| "HODU API ERROR for sending %s / status code: %d / response: %s", | |
| response.url, | |
| response.status_code, | |
| data, | |
| ) | |
| detail = ( | |
| data.get("InternalError") | |
| or data.get("ServiceBusy") | |
| or "Unknown error" | |
| ) | |
| return HoduSubmitErrorResponse(detail=detail) | |
| raw_data = response.json() | |
| mapped_data = { | |
| "status": raw_data.get("status"), | |
| "fields": { | |
| "time": raw_data.get("time"), | |
| "memory": int(raw_data["memory"]) | |
| if raw_data.get("memory") is not None | |
| else None, | |
| "stdout": raw_data.get("stdout"), | |
| "stderr": raw_data.get("stderr"), | |
| }, | |
| } | |
| return HoduSubmitResponse(**mapped_data) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@wacruit/src/apps/hodu/repositories.py` around lines 47 - 74, Update the Hodu
API error-response handling in the visible submission method to parse the
response body only once and reuse that value for both logging and detail
extraction. Catch the JSON decoding failure alongside the existing
ValidationError handling, and return the established HoduSubmitErrorResponse
with a safe fallback detail when a 4xx/5xx response is not valid JSON.