Add fetch timeout/retry, friendly error messages, and VAT rate constant
- fetchWithTimeout (10s) + fetchWithRetry (3 attempts, exponential backoff) - DataError class with type classification (config/network/auth/timeout/unknown) - User-friendly error messages in EN/AR instead of raw error strings - Extract VAT_RATE constant (was hardcoded 1.15) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
14
src/App.tsx
14
src/App.tsx
@@ -5,7 +5,8 @@ import Comparison from './components/Comparison';
|
||||
import Slides from './components/Slides';
|
||||
import { fetchData, getCacheStatus, refreshData } from './services/dataService';
|
||||
import { useLanguage } from './contexts/LanguageContext';
|
||||
import type { MuseumRecord, CacheStatus } from './types';
|
||||
import type { MuseumRecord, CacheStatus, DataErrorType } from './types';
|
||||
import { DataError } from './types';
|
||||
import './App.css';
|
||||
|
||||
interface NavLinkProps {
|
||||
@@ -35,7 +36,7 @@ function App() {
|
||||
const [data, setData] = useState<MuseumRecord[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [refreshing, setRefreshing] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [error, setError] = useState<{ message: string; type: DataErrorType } | null>(null);
|
||||
const [isOffline, setIsOffline] = useState<boolean>(false);
|
||||
const [cacheInfo, setCacheInfo] = useState<CacheStatus | null>(null);
|
||||
const [showDataLabels, setShowDataLabels] = useState<boolean>(false);
|
||||
@@ -62,7 +63,8 @@ function App() {
|
||||
const status = getCacheStatus();
|
||||
setCacheInfo(status);
|
||||
} catch (err) {
|
||||
setError((err as Error).message);
|
||||
const type = err instanceof DataError ? err.type : 'unknown';
|
||||
setError({ message: (err as Error).message, type });
|
||||
console.error(err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -92,8 +94,10 @@ function App() {
|
||||
return (
|
||||
<div className="error-container" dir={dir}>
|
||||
<h2>{t('app.error')}</h2>
|
||||
<p style={{maxWidth: '400px', textAlign: 'center', color: '#64748b'}}>{error}</p>
|
||||
<button onClick={() => window.location.reload()}>{t('app.retry')}</button>
|
||||
<p style={{maxWidth: '400px', textAlign: 'center', color: '#64748b'}}>
|
||||
{t(`errors.${error.type}`)}
|
||||
</p>
|
||||
<button onClick={() => loadData()}>{t('app.retry')}</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user