From 53165a9ef7c560a86ddd8e3c6a9995074129d0ae Mon Sep 17 00:00:00 2001 From: fin Date: Sat, 7 Jun 2025 16:23:58 +0900 Subject: [PATCH] Refactor(API): fixed exception handling issues --- .../workflows/commit-convention-linter.yml | 69 ------ backend/API/guide.txt | 232 ------------------ backend/API/main.py | 16 +- 3 files changed, 15 insertions(+), 302 deletions(-) delete mode 100644 backend/API/guide.txt diff --git a/.github/workflows/commit-convention-linter.yml b/.github/workflows/commit-convention-linter.yml index 521bba2db..eacd40d8c 100644 --- a/.github/workflows/commit-convention-linter.yml +++ b/.github/workflows/commit-convention-linter.yml @@ -1,72 +1,3 @@ -# name: PR Commit Convention Linter - -# on: -# pull_request: -# types: [opened, synchronize, reopened] - -# permissions: -# pull-requests: write - -# jobs: -# commit-lint: -# runs-on: ubuntu-latest - -# steps: - -# - name: Minimal Git clone without actions/checkout -# run: | -# git init -# git remote add origin https://github.com/${{ github.repository }}.git -# git fetch origin ${{ github.event.pull_request.head.ref }} --depth=1 -# git checkout FETCH_HEAD - - -# - name: Install GitHub CLI -# run: | -# sudo apt-get update -# sudo apt-get install -y gh - -# - name: Get latest commit message -# id: get_commit -# run: | -# git log -1 --pretty=format:"%s" > commit.txt - -# - name: Validate commit message -# id: validate -# run: | -# line=$(cat commit.txt) -# echo "Checking commit: $line" - -# # 메시지 길이 확인 (50자 초과면 경고) -# if [[ ${#line} -gt 72 ]]; then -# echo "::warning::⚠️ Commit message is longer than 72 characters." -# fi - -# # 정규식: 타입(scope): 메시지 (소문자 시작, 마침표 금지) -# pattern='^(Feat|Fix|Docs|Style|Refactor|Test|Chore|Ci|Perf|Build)(\([a-zA-Z0-9_-]+\))?: [a-z][^\.]{0,69}$' - -# if ! [[ "$line" =~ $pattern ]] && ! [[ "$line" =~ ^Merge.* ]]; then -# echo "::error::❌ Invalid commit message: $line" -# echo "invalid=1" >> $GITHUB_OUTPUT -# else -# echo "invalid=0" >> $GITHUB_OUTPUT -# fi - -# - name: Comment on PR if invalid -# if: steps.validate.outputs.invalid == '1' -# run: | -# gh pr comment "$PR_NUMBER" --body "🚫 One or more commit messages in this PR **do not follow the commit convention.** - -# Please revise them to match the format: \`Feat(actions): add something cool\` - -# 📘 See our [Wiki](https://github.com/khyeonm/2025_Advanced_Programming/wiki/Git-Commit-Convention) for details. - -# Thank you!" - -# env: -# GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -# PR_NUMBER: ${{ github.event.pull_request.number }} - name: PR Commit Convention Linter on: diff --git a/backend/API/guide.txt b/backend/API/guide.txt deleted file mode 100644 index 3a893a577..000000000 --- a/backend/API/guide.txt +++ /dev/null @@ -1,232 +0,0 @@ -Spectrackr API 사용자 가이드 -========================================== - -Base URL: ---------- -[https://2025advancedprogramming-production.up.railway.app/docs] - -기본 설명: ---------- -Spectrackr API는 채용 정보와 지원자 정보를 조회하는 FastAPI 기반 백엔드입니다. -요청은 POST/GET 방식이며, JSON 형태의 request body를 사용합니다. - -사용 가능한 API 목록: -===================== - -# 회사 기준 검색 -1. /get-company-name-and-detail-job ------------------------------------ -- Method: POST -- 설명: 드롭다운을 위해 직무 카테고리에 해당하는 회사명과 세부 직무 목록을 조회합니다. -- Request Body: - { - "job_category": "IT/인터넷" - } -- Response: - [ - { - "company_name": "KT", - "detail_job": "서버·백엔드" - }, - { - "company_name": "쿠팡", - "detail_job": "서버·백엔드" - }, - ... - ] - - -2. /get-detail-job-by-company-name ----------------------------------- -- Method: POST -- 설명: 드롭다운을 위해 회사 이름에 해당하는 세부 직무 목록을 조회합니다. -- Request Body: - { - "company_name": "KT" - } -- Response: - [ - { - "detail_job": "서버·백엔드" - }, - { - "detail_job": "LLM" - }, - ... - ] - - -3. /get-company-name-by-detail-job ----------------------------------- -- Method: POST -- 설명: 드롭다운을 위해 세부 직무에 해당하는 회사명을 조회합니다. -- Request Body: - { - "detail_job": "LLM" - } -- Response: - [ - { - "company_name": "KT" - }, - { - "company_name": "네이버" - }, - ... - ] - - -4. /get-job-posting -------------------- -- Method: POST -- 설명: 회사, 직무, 카테고리에 해당하는 채용 상세 정보를 조회합니다. -- Request Body: - { - "job_category": "IT/인터넷", - "company_name": "KT", - "detail_job": "서버·백엔드" - } -- Response: - [ - { - "company_type": "", - "main_job": "", - "location": "서울, 경기", - "education_level": "학사", - "major": "", - "experience": "3~5년차, 10년차", - "language_requirement": "", - "military_requirement": "", - "overseas_available": "", - "etc_requirements": "", - "process": "", - "image": "https://d2juy7qzamcf56.cloudfront.net/2025-05-26/d4a3fdd4-7136-4d64-b397-b37f2b62614f.png" - } - ] - -# 스펙 기준 검색 -5. /get-applicants-by-company-detail-job ----------------------------------------- -- Method: POST -- 설명: 회사와 세부 직무에 해당하는 합격자 목록을 조회합니다. -- Request Body: - { - "company": "삼성증권", - "detail_job": "IT 일반" - } -- Response: - [ - { - "id": 3, - "company": "삼성증권", - "detail_job": "IT 일반", - "job_title": null, - "apply_term": "2024 하반기", - "university": "홍익대학교", - "major": "컴퓨터공학과", - "gpa": 3.77, - "gpa_scale": 4.5, - "toeic": 865, - "opic": "IH", - "toeic_speaking": null, - "work_experience": null, - "job_category": "IT/인터넷" - } - ] - - -6. /get-company-by-detail-job ------------------------------- -- Method: POST -- 설명: 드롭다운을 위한 세부 직무로 구분한 회사 목록을 조회합니다. -- Request Body: - { - "detail_job": "IT 일반" - } -- Response: - [ - { - "company": "KB부동산신탁" - }, - { - "company": "현대 글로비스" - }, - ... - ] - - -7. /get-detail-job-by-company ------------------------------ -- Method: POST -- 설명: 특정 회사에 지원한 직무 목록 조회 -- Request Body: - { - "company": "네이버" - } -- Response: - [ - { - "detail_job": "기술연구소/센터" - } - ] - - -8. /get-all-universities ------------------------- -- Method: GET -- 설명: 드롭다운을 위해 모든 지원자의 대학교 목록을 반환합니다. -- Response: - [ - "지방거주 사립대", - "영남대학교", - ... - ] - - -9. /get-applicants-by-school ----------------------------- -- Method: POST -- 설명: 특정 대학교 출신 지원자들이 지원한 회사 및 직무를 조회합니다. -- Request Body: - { - "university": "부산대학교" - } -- Response: - [ - { - "company": "기아", - "detail_job": "생산관리" - }, - { - "company": "기아", - "detail_job": "생산기술" - }, - ... - ] - - -# default -10. / (루트) ----------- -- Method: GET -- 설명: 서버 상태 확인용 엔드포인트입니다. -- Response: - { - "message": "Spectrackr API is live!" - } - - -오류 코드 안내: -=============== -- 200 OK: 요청 성공 -- 400 Bad Request: 잘못된 요청 데이터 -- 404 Not Found: 데이터 없음 -- 500 Internal Server Error: 서버 에러 - -주의사항: -========= -- 모든 POST 요청은 JSON 형식의 Body를 포함해야 합니다. -- 응답 데이터는 대부분 리스트 형식이며, 하나의 JSON 객체로 구성된 항목들이 포함됩니다. - -작성 날짜: 2025-06-05 -최종 수정: 2025-06-06 \ No newline at end of file diff --git a/backend/API/main.py b/backend/API/main.py index 1bae05deb..11d3f4512 100644 --- a/backend/API/main.py +++ b/backend/API/main.py @@ -6,6 +6,13 @@ from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import text from functools import wraps +import logging + +# --- logger 설정 --- +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + # --- Factory Pattern --- class RequestFactory: @@ -28,8 +35,15 @@ def safe_handler(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) + except ValueError as ve: + logger.warning(f"400 Bad Request: {ve}") + raise HTTPException(status_code=400, detail=str(ve)) + except KeyError as ke: + logger.warning(f"404 Not Found: {ke}") + raise HTTPException(status_code=404, detail=f"Not Found: {ke}") except Exception as e: - raise HTTPException(status_code=500, detail=str(e)) + logger.error(f"500 Internal Server Error: {e}", exc_info=True) + raise HTTPException(status_code=500, detail="Internal Server Error") return wrapper # --- FastAPI ---