Remove str(e) from 4xx and per-row error bodies #68

Open
opened 2026-10-03 19:44:43 +00:00 by jalenluorion · 0 comments
Member

What's wrong
Generic 500 bodies landed in #21, but a few non-500 responses still return raw exception text:

  • GET /api/organizations/get_courses: 404 with str(e) of a FileNotFoundError, which includes the server file path (api/app/utils/course_data.py L18).
  • DELETE /api/organizations/<org_id>/calendar-sources/<id>/events: 404 with str(e) of a ValueError.
  • DELETE /api/google/unauthorize: 400 with str(e) of any exception, including network errors from the token revoke call.
  • POST /api/organizations/bulk_create_admins: each failed email adds f"Error processing {email}: {str(e)}" to the 201 body, which can include SQL.

How to reproduce
In a test, mock app.api.organizations.get_course_data to raise FileNotFoundError("File not found: /srv/secret/path.json"), then GET /api/organizations/get_courses. The path is in the body.

Expected
A fixed message (e.g. "Course data not available", "Calendar source not found", "Could not disconnect Google", "Could not add "), with the detail written to the log by log.exception. Unauthorize failures should be 502 or 500, not 400.

Where to look

  • api/app/api/organizations.py L271-272, L391-392, L589-590.
  • api/app/api/google.py unauthorize_google() L64-72.
  • Line numbers are from main at 2c5f2e9.

Done when

  • no response body contains exception text
  • tests in api/tests/api/test_error_responses.py that mock each failure and assert the body has none of the exception message
**What's wrong** Generic 500 bodies landed in #21, but a few non-500 responses still return raw exception text: - `GET /api/organizations/get_courses`: 404 with `str(e)` of a FileNotFoundError, which includes the server file path (`api/app/utils/course_data.py` L18). - `DELETE /api/organizations/<org_id>/calendar-sources/<id>/events`: 404 with `str(e)` of a ValueError. - `DELETE /api/google/unauthorize`: 400 with `str(e)` of any exception, including network errors from the token revoke call. - `POST /api/organizations/bulk_create_admins`: each failed email adds `f"Error processing {email}: {str(e)}"` to the 201 body, which can include SQL. **How to reproduce** In a test, mock `app.api.organizations.get_course_data` to raise `FileNotFoundError("File not found: /srv/secret/path.json")`, then GET `/api/organizations/get_courses`. The path is in the body. **Expected** A fixed message (e.g. "Course data not available", "Calendar source not found", "Could not disconnect Google", "Could not add <email>"), with the detail written to the log by `log.exception`. Unauthorize failures should be 502 or 500, not 400. **Where to look** - `api/app/api/organizations.py` L271-272, L391-392, L589-590. - `api/app/api/google.py` `unauthorize_google()` L64-72. - Line numbers are from main at 2c5f2e9. **Done when** - [ ] no response body contains exception text - [ ] tests in `api/tests/api/test_error_responses.py` that mock each failure and assert the body has none of the exception message
jalenluorion added this to the Phase 2 milestone 2026-10-03 19:44:43 +00:00
jalenluorion added this to the CMUCal project 2026-10-03 19:45:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ScottyLabs/cal#68
No description provided.