Files
openhuman/src/App.tsx
T
27b5c2800e Add user-facing error handling with opt-in reporting (#81)
* chore: add CI secrets management and local testing script

- Added ci-secrets.example.json to provide a template for CI secrets configuration.
- Introduced test-ci-local.sh script to facilitate local testing of the package-and-publish workflow using act.
- Updated .gitignore to exclude the actual ci-secrets.json file containing sensitive tokens.

* Add user-facing error handling system with opt-in reporting

Intercept all errors (React, global JS, skill runtime) and show non-blocking
notifications that let users inspect the exact sanitized payload before
choosing to report or dismiss. Errors are no longer auto-sent to Sentry.

- Add error report queue (errorReportQueue.ts) with subscribe/notify pattern
- Add ErrorReportNotification rendered in isolated React root (survives crashes)
- Add ErrorFallbackScreen for catastrophic React boundary errors
- Wire Sentry beforeSend to queue errors instead of auto-sending
- Add skill runtime error capture via runtime:skill-status-changed listener

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove conflicting Telegram API fields from ci-secrets.example.json

* Strip sensitive fields from exception before queuing for user review

Sanitize stacktrace frames to remove local variables (vars), source code
context lines (context_line, pre_context, post_context), and mechanism.data.
Only safe location metadata (filename, function, lineno, colno, in_app)
is retained in the sanitized event shown to the user.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Compute analyticsEnabled on each render instead of caching with useMemo

The Report button now reflects the current analytics setting immediately
when the user toggles it in Settings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Refactor components for improved readability and consistency

- Adjusted formatting in ErrorFallbackScreen and ErrorReportNotification components for better JSX structure.
- Removed unnecessary line breaks in Home component for cleaner layout.
- Streamlined error handling logic in SkillProvider for clarity.
- Enhanced errorReportQueue with consistent object formatting for better maintainability.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:02:07 +05:30

59 lines
2.3 KiB
TypeScript

import * as Sentry from '@sentry/react';
import { Provider } from 'react-redux';
import { HashRouter as Router } from 'react-router-dom';
import { PersistGate } from 'redux-persist/integration/react';
import AppRoutes from './AppRoutes';
import ErrorFallbackScreen from './components/ErrorFallbackScreen';
import MiniSidebar from './components/MiniSidebar';
import AIProvider from './providers/AIProvider';
import SkillProvider from './providers/SkillProvider';
import SocketProvider from './providers/SocketProvider';
import UserProvider from './providers/UserProvider';
import { tagErrorSource } from './services/errorReportQueue';
import { persistor, store } from './store';
function App() {
return (
<Sentry.ErrorBoundary
fallback={({ error, componentStack, resetError }) => (
<ErrorFallbackScreen error={error} componentStack={componentStack} onReset={resetError} />
)}
onError={(_error, componentStack, eventId) => {
tagErrorSource(eventId, 'react', componentStack);
}}>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<UserProvider>
<SocketProvider>
<AIProvider>
<SkillProvider>
<Router>
<div className="relative h-screen flex flex-col overflow-hidden">
<div className="flex-1 flex overflow-hidden">
<MiniSidebar />
<div className="flex flex-col flex-1 relative overflow-hidden">
<div className="flex-1 overflow-y-auto">
<AppRoutes />
</div>
<div className="pointer-events-none flex-shrink-0 flex justify-center z-50">
<div className="w-full px-3 py-1.5 text-[9px] uppercase tracking-[0.18em] text-white/40 text-center">
AlphaHuman is in early beta. Version 0.1.0
</div>
</div>
</div>
</div>
</div>
</Router>
</SkillProvider>
</AIProvider>
</SocketProvider>
</UserProvider>
</PersistGate>
</Provider>
</Sentry.ErrorBoundary>
);
}
export default App;