Archived
- add uv configuration for the backend - update frontend to make auth work - add new auth endpoints - add bookmars feat - add reader feat
41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
import axios from "axios";
|
|
|
|
function messagesFromValue(value: unknown): string[] {
|
|
if (value == null) return [];
|
|
if (typeof value === "string") return [value];
|
|
if (Array.isArray(value)) return value.flatMap(messagesFromValue);
|
|
if (typeof value === "object") {
|
|
const record = value as Record<string, unknown>;
|
|
if ("detail" in record) {
|
|
const fromDetail = messagesFromValue(record.detail);
|
|
if (fromDetail.length > 0) return fromDetail;
|
|
}
|
|
const messages: string[] = [];
|
|
for (const [key, nested] of Object.entries(record)) {
|
|
if (key === "detail") continue;
|
|
for (const part of messagesFromValue(nested)) {
|
|
messages.push(key === "non_field_errors" ? part : `${key}: ${part}`);
|
|
}
|
|
}
|
|
return messages;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/** Extract human-readable message(s) from a Django REST Framework / axios error response. */
|
|
export function getApiErrorMessage(err: unknown, fallback = "Something went wrong"): string {
|
|
if (axios.isAxiosError(err)) {
|
|
const data = err.response?.data;
|
|
if (data !== undefined) {
|
|
const messages = messagesFromValue(data);
|
|
if (messages.length > 0) return messages.join(". ");
|
|
}
|
|
if (err.response?.status && err.message.startsWith("Request failed")) {
|
|
return fallback;
|
|
}
|
|
return err.message || fallback;
|
|
}
|
|
if (err instanceof Error) return err.message;
|
|
return fallback;
|
|
}
|