name: oneticket-safety-for-vite-react-primer description: "Ensure every new application created from this template has a minimal, generic error boundary at startup and at the UI/root level, based on cross-language error handling patterns." version: "1.0.0"
App First-Generation Safety
Objective
When creating a new application (frontend, backend, CLI) from this template, always provide a minimal but robust safety net:
- a global error boundary around the startup/bootstrap path, and
- for UI frameworks that support it, a top-level UI error boundary,
so that:
- unexpected errors do not result in silent crashes or blank screens, and
- users still see a controlled fallback message plus copyable technical details.
This skill complements the generic patterns from wshobson/error-handling-patterns and specializes them for this template.
version: "1.0.0"
When to Use
Use this skill whenever:
architecture.mddefines a new application (web frontend, backend service, CLI, worker, etc.), and- you are implementing its first generation (initial bootstrap / entrypoint).
Examples:
- creating a new SPA frontend under
apps/<current_project>/frontend/, - adding a new backend service under
apps/<current_project>/backend/, - adding a new CLI entrypoint.
version: "1.0.0"
Core Principles
Single boundary per layer
- Each application should have:
- one startup boundary that wraps the main bootstrap path, and
- if applicable, one UI boundary at the top of the visual tree.
- Each application should have:
Generic, not feature-specific
- Boundaries are generic: they transform any unexpected error into:
- a clean fallback message for users, and
- detailed logs / technical details for developers.
- Do not special-case particular features (e.g. MSW vs something else) inside the boundary.
- Boundaries are generic: they transform any unexpected error into:
Separation of concerns
- Local error handling (e.g. validation errors, expected failures) is still handled near the source.
- Boundaries are a last resort for unexpected, unrecoverable errors.
version: "1.0.0"
Process
Step 1 – Identify application type and entrypoint(s)
- Read
architecture.mdto determine:- whether the app is a frontend, backend service, CLI, etc.,
- what the main entrypoints are (e.g.
main.tsx,server.ts,cli.ts).
- For each new application, choose the appropriate boundary mapping:
- Web frontend (React, etc.):
- Startup boundary around the bootstrap function (
main()/bootstrap()), - UI boundary (top-level Error Boundary component).
- Startup boundary around the bootstrap function (
- Backend HTTP service:
- Startup boundary around the server bootstrap (e.g.
main()/startServer()), - Global error handler / middleware for HTTP requests.
- Startup boundary around the server bootstrap (e.g.
- CLI / worker:
- Startup boundary around
main()that converts unexpected errors into:- exit codes,
- concise terminal output with copyable technical details.
- Startup boundary around
- Web frontend (React, etc.):
Step 2 – Apply startup boundary (all app types)
For any new application:
- Wrap the main bootstrap path in a
main()(or equivalent) that:- calls lower-level
bootstrap()/run()functions, and - is wrapped in a
try { ... } catch (error) { ... }(or language-idiomatic equivalent).
- calls lower-level
- In the
catch:- log a generic message and the error details (stack, context),
- produce a safe fallback output:
- web UI → error screen with generic message +
<details><pre>or equivalent for copyable details, - backend → structured error (e.g. JSON) plus reliable HTTP status,
- CLI → human-readable message plus enough detail that can be copy–pasted.
- web UI → error screen with generic message +
- Do not silently swallow errors; boundaries must be observable (log + fallback).
Step 3 – Apply UI error boundary (for frontends)
For frontends using a UI framework that supports error boundaries (e.g. React):
- Create a top-level Error Boundary component (for example
AppErrorBoundaryin React) that:- catches rendering / lifecycle errors,
- logs a generic “Unexpected UI error” and technical details,
- renders a generic error screen with:
- a short explanation for users,
- a toggle (
<details>, dialog, or similar) containing copyable technical details (message + stack).
- Wrap the root app component with this boundary in the entrypoint:
- React example:
createRoot(...).render(<AppErrorBoundary><App /></AppErrorBoundary>)
- React example:
- Keep the boundary generic:
- no feature-specific logic inside (
if (error is from MSW) ...), - it simply transforms arbitrary exceptions into an understandable fallback.
- no feature-specific logic inside (
Step 4 – Keep boundaries aligned with error-handling-patterns
When implementing boundaries:
- Use
wshobson/error-handling-patternsto guide:- how you structure error types (ApplicationError, ValidationError, etc.),
- what is considered recoverable vs unrecoverable.
- Position boundaries at the edges:
- process boundaries (startup / main),
- user-visible boundaries (UI root, HTTP global handler),
- not deep inside local feature code.
version: "1.0.0"
React + Vite Frontend Mapping (current stack)
For the React + Vite SPA described in docs/<current_project>/architecture.md and implemented under apps/<current_project>/frontend/:
Startup boundary:
- Implement a
main()function inapps/<current_project>/frontend/src/main.tsxthat:- calls
bootstrap()(which may include MSW setup and React rendering), - wraps the call in a
try/catchand renders an "Unexpected startup error" screen with copyable technical details.
- calls
- Implement a
UI boundary:
- Implement an
AppErrorBoundarycomponent underapps/<current_project>/frontend/src/root/(or equivalent), - Wrap
<App />with<AppErrorBoundary>in the React root.
- Implement an
This pattern ensures:
- no silent blank screen on unexpected errors,
- consistent error surfaces with both user-friendly text and copyable debug info.