fix: expose actionable API error details
This commit is contained in:
+52
-4
@@ -1,17 +1,65 @@
|
||||
import logging
|
||||
|
||||
from rest_framework.views import exception_handler as drf_exception_handler
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _error_messages(details):
|
||||
messages = []
|
||||
|
||||
def collect(value):
|
||||
if isinstance(value, dict):
|
||||
for item in value.values():
|
||||
collect(item)
|
||||
elif isinstance(value, (list, tuple)):
|
||||
for item in value:
|
||||
collect(item)
|
||||
elif value is not None:
|
||||
message = str(value).strip()
|
||||
if message and message not in messages:
|
||||
messages.append(message)
|
||||
|
||||
collect(details)
|
||||
return messages
|
||||
|
||||
|
||||
def _error_message(details):
|
||||
messages = _error_messages(details)
|
||||
if not messages:
|
||||
return "请求未能完成"
|
||||
return ";".join(messages)[:300]
|
||||
|
||||
|
||||
def exception_handler(exc, context):
|
||||
response = drf_exception_handler(exc, context)
|
||||
request = context.get("request")
|
||||
if response is None:
|
||||
logger.exception(
|
||||
"api_unhandled_error method=%s path=%s",
|
||||
getattr(request, "method", "-"),
|
||||
getattr(request, "path", "-"),
|
||||
)
|
||||
return response
|
||||
|
||||
request = context.get("request")
|
||||
details = response.data
|
||||
code = getattr(exc, "default_code", "request_error")
|
||||
message = _error_message(details)
|
||||
fields = ",".join(details.keys()) if isinstance(details, dict) else "-"
|
||||
logger.info(
|
||||
"api_request_error method=%s path=%s status=%s code=%s fields=%s message=%s",
|
||||
getattr(request, "method", "-"),
|
||||
getattr(request, "path", "-"),
|
||||
response.status_code,
|
||||
code,
|
||||
fields,
|
||||
message,
|
||||
)
|
||||
response.data = {
|
||||
"error": {
|
||||
"code": getattr(exc, "default_code", "request_error"),
|
||||
"message": "请求未能完成",
|
||||
"details": response.data,
|
||||
"code": code,
|
||||
"message": message,
|
||||
"details": details,
|
||||
"request_id": getattr(request, "request_id", None),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user