78 lines
No EOL
2.2 KiB
TypeScript
78 lines
No EOL
2.2 KiB
TypeScript
import { useState, useCallback } from 'react';
|
|
import api from '../api';
|
|
|
|
// Generic API error handling
|
|
export function formatApiError(error: any, defaultMessage: string): string {
|
|
if (error.response) {
|
|
const data = error.response.data;
|
|
|
|
// Handle FastAPI validation errors (detail is an array)
|
|
if (data?.detail && Array.isArray(data.detail)) {
|
|
return data.detail.map((err: any) => {
|
|
if (typeof err === 'string') return err;
|
|
if (err.msg) return `${err.loc?.join('.') || 'field'}: ${err.msg}`;
|
|
return JSON.stringify(err);
|
|
}).join(', ');
|
|
}
|
|
|
|
// Handle other error formats
|
|
if (typeof data?.detail === 'string') return data.detail;
|
|
if (typeof data?.message === 'string') return data.message;
|
|
if (typeof data === 'string') return data;
|
|
|
|
return defaultMessage;
|
|
} else if (error.request) {
|
|
return 'Keine Antwort vom Server erhalten';
|
|
} else {
|
|
return error.message || defaultMessage;
|
|
}
|
|
}
|
|
|
|
// Type for API request options
|
|
export interface ApiRequestOptions<T> {
|
|
url: string;
|
|
method: 'get' | 'post' | 'put' | 'delete';
|
|
data?: T;
|
|
params?: Record<string, string | number | boolean>;
|
|
additionalConfig?: Record<string, any>; // For responseType, headers, etc.
|
|
}
|
|
|
|
// Hook for making API requests with consistent error handling
|
|
export function useApiRequest<RequestData = any, ResponseData = any>() {
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const request = useCallback(async ({
|
|
url,
|
|
method,
|
|
data,
|
|
params,
|
|
additionalConfig = {}
|
|
}: ApiRequestOptions<RequestData>): Promise<ResponseData> => {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await api({
|
|
url,
|
|
method,
|
|
data,
|
|
params,
|
|
...additionalConfig
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
const errorMessage = formatApiError(error, `Fehler bei ${method.toUpperCase()} ${url}`);
|
|
setError(errorMessage);
|
|
throw new Error(String(errorMessage)); // Ensure it's a string
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
return {
|
|
request,
|
|
isLoading,
|
|
error
|
|
};
|
|
}
|