Улучшена обработка ошибок валидации: парсинг detail с извлечением имени поля и сообщения, обработка API ошибок в try-except

This commit is contained in:
admin i 2025-12-02 11:07:47 +03:00
parent e6e39b7fd0
commit 5aa8149514
2 changed files with 93 additions and 8 deletions

View File

@ -529,8 +529,15 @@ def employee_edit(request, pk: int):
logger.info(f"[employee_edit] Final payload keys: {list(payload.keys())}")
# Отправляем в DRF как JSON (с base64 аватаром)
resp = api.patch(f"v1/employees/{pk}/", json=payload)
logger.info(f"[employee_edit] API response status: {resp.status}")
try:
resp = api.patch(f"v1/employees/{pk}/", json=payload)
logger.info(f"[employee_edit] API response status: {resp.status}")
except Exception as e:
logger.error(f"[employee_edit] API call error: {e}")
return JsonResponse(
{"detail": f"API error: {str(e)}"},
status=500
)
else:
# Обрабатываем JSON (как раньше)
logger.info("[employee_edit] Processing JSON")
@ -539,11 +546,20 @@ def employee_edit(request, pk: int):
except Exception as e:
logger.error(f"[employee_edit] JSON parse error: {e}")
payload = {}
resp = api.patch(f"v1/employees/{pk}/", json=payload)
try:
resp = api.patch(f"v1/employees/{pk}/", json=payload)
except Exception as e:
logger.error(f"[employee_edit] API call error: {e}")
return JsonResponse(
{"detail": f"API error: {str(e)}"},
status=500
)
try:
data = resp.json
except Exception:
except Exception as e:
logger.error(f"[employee_edit] Response JSON parse error: {e}")
data = {"detail": resp.text}
# Всегда возвращаем JSON без редиректа
@ -625,8 +641,15 @@ def employee_edit_me(request):
)
# Отправляем в DRF как JSON (с base64 аватаром)
resp = api.patch("v1/employees/me/", json=payload)
logger.info(f"[employee_edit_me] API response status: {resp.status}")
try:
resp = api.patch("v1/employees/me/", json=payload)
logger.info(f"[employee_edit_me] API response status: {resp.status}")
except Exception as e:
logger.error(f"[employee_edit_me] API call error: {e}")
return JsonResponse(
{"detail": f"API error: {str(e)}"},
status=500
)
else:
# Обрабатываем JSON (как раньше)
logger.info("[employee_edit_me] Processing JSON")
@ -635,11 +658,20 @@ def employee_edit_me(request):
except Exception as e:
logger.error(f"[employee_edit_me] JSON parse error: {e}")
payload = {}
resp = api.patch("v1/employees/me/", json=payload)
try:
resp = api.patch("v1/employees/me/", json=payload)
except Exception as e:
logger.error(f"[employee_edit_me] API call error: {e}")
return JsonResponse(
{"detail": f"API error: {str(e)}"},
status=500
)
try:
data = resp.json
except Exception:
except Exception as e:
logger.error(f"[employee_edit_me] Response JSON parse error: {e}")
data = {"detail": resp.text}
# Всегда возвращаем JSON без редиректа

View File

@ -107,6 +107,54 @@ function displayFormErrors(form, errors) {
}
if (typeof errors === 'object') {
// Обрабатываем специальный случай с полем "detail"
if (errors.detail && Object.keys(errors).length === 1) {
// Пытаемся распарсить detail, если там есть информация о полях
const detailStr = String(errors.detail);
// Проверяем, есть ли в detail информация о конкретных полях
// Формат: "Internal server error: {'field': [ErrorDetail(...)]}"
const fieldMatch = detailStr.match(/\{'(\w+)':\s*\[(.*?)\]/);
if (fieldMatch) {
const fieldName = fieldMatch[1];
const errorText = fieldMatch[2];
// Извлекаем читаемое сообщение об ошибке
const msgMatch = errorText.match(/ErrorDetail\(string='([^']+)'/);
const errorMessage = msgMatch ? msgMatch[1] : errorText;
// Показываем ошибку в конкретном поле
const field = form.querySelector(`[name="${fieldName}"]`);
if (field) {
field.classList.add('is-invalid');
let feedbackEl = field.parentElement.querySelector('.invalid-feedback');
if (!feedbackEl) {
feedbackEl = document.createElement('div');
feedbackEl.className = 'invalid-feedback';
field.parentElement.appendChild(feedbackEl);
}
feedbackEl.textContent = errorMessage;
feedbackEl.style.display = 'block';
console.log(`[EmployeeForm] Ошибка в поле ${fieldName}:`, errorMessage);
} else {
// Если поле не найдено, показываем общую ошибку
showErrorMessage(errorMessage);
}
} else {
// Если не удалось распарсить, показываем как общую ошибку
showErrorMessage(detailStr);
}
return;
}
// Стандартная обработка ошибок по полям
Object.keys(errors).forEach(fieldName => {
const errorMessages = Array.isArray(errors[fieldName])
? errors[fieldName]
@ -133,8 +181,13 @@ function displayFormErrors(form, errors) {
feedbackEl.style.display = 'block';
console.log(`[EmployeeForm] Ошибка в поле ${fieldName}:`, errorMessages);
} else if (fieldName === 'non_field_errors') {
// Общие ошибки формы
showErrorMessage(errorMessages.join(', '));
} else {
console.warn(`[EmployeeForm] Поле ${fieldName} не найдено в форме`);
// Показываем как общую ошибку
showErrorMessage(`${fieldName}: ${errorMessages.join(', ')}`);
}
});
}