54 lines
1.5 KiB
JavaScript
54 lines
1.5 KiB
JavaScript
const BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:9292';
|
|
|
|
/**
|
|
* Make an HTTP request with automatic token header injection and error handling.
|
|
*/
|
|
export async function request(endpoint, options = {}) {
|
|
const token = localStorage.getItem('authsec_token');
|
|
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
...options.headers,
|
|
};
|
|
|
|
const url = endpoint.startsWith('http') ? endpoint : `${BASE_URL}${endpoint}`;
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
...options,
|
|
headers,
|
|
});
|
|
|
|
const contentType = response.headers.get('content-type');
|
|
let data;
|
|
|
|
if (contentType && contentType.includes('application/json')) {
|
|
data = await response.json();
|
|
} else {
|
|
data = await response.text();
|
|
}
|
|
|
|
if (!response.ok) {
|
|
const errorMessage =
|
|
(typeof data === 'object' && (data.operationMessage || data.message || data.error)) ||
|
|
(typeof data === 'string' && data) ||
|
|
`HTTP Error: ${response.status}`;
|
|
const err = new Error(errorMessage);
|
|
err.status = response.status;
|
|
err.data = data;
|
|
throw err;
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
// If network fetch fails completely (e.g. backend server is not running)
|
|
if (error.name === 'TypeError' && error.message.includes('fetch')) {
|
|
const netErr = new Error('Cannot reach Spring Boot server at ' + BASE_URL + '. Is backend running?');
|
|
netErr.isNetworkError = true;
|
|
throw netErr;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|