feat: Sentry monitoring a kompletnější sledování stavů Bolt Food
- integrace Sentry na serveru (@sentry/node) i klientu (@sentry/react): chyby 5xx, pády a console logy se hlásí do self-hosted Sentry - nový veřejný endpoint GET /api/config — klient si z něj za běhu vyzvedne Sentry DSN (SENTRY_DSN / SENTRY_CLIENT_DSN v env) - ErrorBoundary na klientu a sourcemapy pro čitelné stack traces - oprava mapování stavu waiting_acceptance (zobrazoval se jako Příprava) - mapování stavů kurýra matched/accepted, logování přechodů stavů Bolt objednávek pro postupné zmapování nedokumentovaného API - simulátor Bolt ve vývoji nově prochází celou reálnou sekvenci stavů - vypnuté logování connect/disconnect websocket klientů
This commit is contained in:
+31
-5
@@ -6,20 +6,38 @@ import './index.css';
|
||||
import AppRoutes from './AppRoutes';
|
||||
import { BrowserRouter } from 'react-router';
|
||||
import { client } from '../../types/gen/client.gen';
|
||||
import { getConfig } from '../../types/gen/sdk.gen';
|
||||
import { getToken } from './Utils';
|
||||
import { toast } from 'react-toastify';
|
||||
import * as Sentry from '@sentry/react';
|
||||
|
||||
client.setConfig({
|
||||
auth: () => getToken(),
|
||||
baseUrl: '/api', // openapi-ts si to z nějakého důvodu neumí převzít z api.yml
|
||||
});
|
||||
|
||||
// Sentry se inicializuje až podle runtime konfigurace ze serveru (bez DSN zůstává vypnuté).
|
||||
// Klient je statický build, takže DSN nejde zapéct při buildu — server ho zná z env.
|
||||
getConfig().then(({ data }) => {
|
||||
if (data?.sentry.dsn) {
|
||||
Sentry.init({
|
||||
dsn: data.sentry.dsn,
|
||||
environment: data.sentry.environment,
|
||||
enableLogs: true,
|
||||
});
|
||||
}
|
||||
}).catch(() => { /* config endpoint nedostupný — běžíme bez Sentry */ });
|
||||
|
||||
// Interceptor na vyhození toasteru při chybě
|
||||
client.interceptors.response.use(async response => {
|
||||
// TODO opravit - login je zatím výjimka, voláme ho "naprázdno" abychom zjistili, zda nás nepřihlásily trusted headers
|
||||
if (!response.ok && !response.url.includes("/login")) {
|
||||
const json = await response.json();
|
||||
toast.error(json.error, { theme: "colored" });
|
||||
// Serverové chyby hlásíme do Sentry; 4xx jsou očekávané (chyby uživatele)
|
||||
if (response.status >= 500) {
|
||||
Sentry.captureMessage(`API ${response.status}: ${new URL(response.url).pathname} — ${json.error}`, 'error');
|
||||
}
|
||||
}
|
||||
return response;
|
||||
});
|
||||
@@ -29,10 +47,18 @@ const root = ReactDOM.createRoot(
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<ProvideAuth>
|
||||
<AppRoutes />
|
||||
</ProvideAuth>
|
||||
</BrowserRouter>
|
||||
<Sentry.ErrorBoundary fallback={
|
||||
<div className="text-center p-5">
|
||||
<h4>Něco se pokazilo 😕</h4>
|
||||
<p>Chyba byla nahlášena. Zkuste stránku načíst znovu.</p>
|
||||
<button className="btn btn-primary" onClick={() => window.location.reload()}>Načíst znovu</button>
|
||||
</div>
|
||||
}>
|
||||
<BrowserRouter>
|
||||
<ProvideAuth>
|
||||
<AppRoutes />
|
||||
</ProvideAuth>
|
||||
</BrowserRouter>
|
||||
</Sentry.ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user