Skip to content

Commit eea896a

Browse files
tangmc0210claude
andcommitted
fix(api): emit canonical field-error items in timetable and pku_account envelopes
Validation errors now carry errors: {field: [{code, message}]}, the shape of the platform-wide envelope introduced by api/exceptions.py (PR #1014) and parsed by the mini-program's unified RequestError (YPPF-mini #10). Switching these modules to StandardizedExceptionHandlerMixin is a mechanical follow-up once #1014 lands. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012t4BD5H1P5nn2zF7oU6q9e
1 parent 9247667 commit eea896a

2 files changed

Lines changed: 21 additions & 4 deletions

File tree

api/pku_account/views.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,25 @@ def _first_message(errors: Any) -> str:
112112
return str(errors)
113113

114114

115+
def _field_errors(errors: Any) -> dict[str, list[dict[str, str]]]:
116+
# Canonical ``{field: [{code, message}]}`` shape shared with api/exceptions.py.
117+
if not isinstance(errors, dict):
118+
return {}
119+
result: dict[str, list[dict[str, str]]] = {}
120+
for name, value in errors.items():
121+
values = value if isinstance(value, (list, tuple)) else [value]
122+
result[str(name)] = [
123+
{'code': str(getattr(item, 'code', None) or 'invalid'), 'message': str(item)}
124+
for item in values]
125+
return result
126+
127+
115128
def _invalid(errors: Any) -> Response:
116129
return Response(
117130
{
118131
'code': 'INVALID_INPUT',
119132
'message': _first_message(errors),
120-
'errors': errors,
133+
'errors': _field_errors(errors),
121134
},
122135
status=status.HTTP_400_BAD_REQUEST,
123136
)

api/timetable/views.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,19 @@ def _first_error(detail) -> str:
102102
return str(detail)
103103

104104

105-
def _field_errors(detail) -> dict[str, list[str]]:
105+
def _field_errors(detail) -> dict[str, list[dict[str, str]]]:
106+
"""Canonical field errors: ``{field: [{code, message}]}`` (same shape as
107+
the platform-wide envelope of ``api/exceptions.py``)."""
106108
if not isinstance(detail, dict):
107109
return {}
108-
errors: dict[str, list[str]] = {}
110+
errors: dict[str, list[dict[str, str]]] = {}
109111
for name, value in detail.items():
110112
if name == 'detail':
111113
continue
112114
values = value if isinstance(value, (list, tuple)) else [value]
113-
errors[str(name)] = [str(item) for item in values]
115+
errors[str(name)] = [
116+
{'code': str(getattr(item, 'code', None) or 'invalid'), 'message': str(item)}
117+
for item in values]
114118
return errors
115119

116120

0 commit comments

Comments
 (0)