ai-flow-dev 2.7.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +573 -570
  3. package/package.json +74 -74
  4. package/prompts/backend/flow-build-phase-0.md +535 -535
  5. package/prompts/backend/flow-build-phase-1.md +626 -626
  6. package/prompts/backend/flow-build-phase-10.md +340 -340
  7. package/prompts/backend/flow-build-phase-2.md +573 -573
  8. package/prompts/backend/flow-build-phase-3.md +834 -834
  9. package/prompts/backend/flow-build-phase-4.md +554 -554
  10. package/prompts/backend/flow-build-phase-5.md +703 -703
  11. package/prompts/backend/flow-build-phase-6.md +524 -524
  12. package/prompts/backend/flow-build-phase-7.md +1001 -1001
  13. package/prompts/backend/flow-build-phase-8.md +1407 -1407
  14. package/prompts/backend/flow-build-phase-9.md +477 -477
  15. package/prompts/backend/flow-build.md +137 -137
  16. package/prompts/backend/flow-check-review.md +656 -20
  17. package/prompts/backend/flow-check-test.md +526 -14
  18. package/prompts/backend/flow-check.md +717 -67
  19. package/prompts/backend/flow-commit.md +88 -119
  20. package/prompts/backend/flow-docs-sync.md +354 -354
  21. package/prompts/backend/flow-finish.md +919 -0
  22. package/prompts/backend/flow-release.md +949 -0
  23. package/prompts/backend/flow-work-feature.md +61 -61
  24. package/prompts/backend/flow-work-fix.md +46 -46
  25. package/prompts/backend/flow-work-refactor.md +48 -48
  26. package/prompts/backend/flow-work-resume.md +34 -34
  27. package/prompts/backend/flow-work.md +1098 -1286
  28. package/prompts/desktop/flow-build-phase-0.md +359 -359
  29. package/prompts/desktop/flow-build-phase-1.md +295 -295
  30. package/prompts/desktop/flow-build-phase-10.md +357 -357
  31. package/prompts/desktop/flow-build-phase-2.md +282 -282
  32. package/prompts/desktop/flow-build-phase-3.md +291 -291
  33. package/prompts/desktop/flow-build-phase-4.md +308 -308
  34. package/prompts/desktop/flow-build-phase-5.md +269 -269
  35. package/prompts/desktop/flow-build-phase-6.md +350 -350
  36. package/prompts/desktop/flow-build-phase-7.md +297 -297
  37. package/prompts/desktop/flow-build-phase-8.md +541 -541
  38. package/prompts/desktop/flow-build-phase-9.md +439 -439
  39. package/prompts/desktop/flow-build.md +156 -156
  40. package/prompts/desktop/flow-check-review.md +656 -20
  41. package/prompts/desktop/flow-check-test.md +526 -14
  42. package/prompts/desktop/flow-check.md +717 -67
  43. package/prompts/desktop/flow-commit.md +88 -119
  44. package/prompts/desktop/flow-docs-sync.md +354 -354
  45. package/prompts/desktop/flow-finish.md +919 -0
  46. package/prompts/desktop/flow-release.md +662 -0
  47. package/prompts/desktop/flow-work-feature.md +61 -61
  48. package/prompts/desktop/flow-work-fix.md +46 -46
  49. package/prompts/desktop/flow-work-refactor.md +48 -48
  50. package/prompts/desktop/flow-work-resume.md +34 -34
  51. package/prompts/desktop/flow-work.md +1202 -1390
  52. package/prompts/frontend/flow-build-phase-0.md +425 -425
  53. package/prompts/frontend/flow-build-phase-1.md +626 -626
  54. package/prompts/frontend/flow-build-phase-10.md +33 -33
  55. package/prompts/frontend/flow-build-phase-2.md +573 -573
  56. package/prompts/frontend/flow-build-phase-3.md +782 -782
  57. package/prompts/frontend/flow-build-phase-4.md +554 -554
  58. package/prompts/frontend/flow-build-phase-5.md +703 -703
  59. package/prompts/frontend/flow-build-phase-6.md +524 -524
  60. package/prompts/frontend/flow-build-phase-7.md +1001 -1001
  61. package/prompts/frontend/flow-build-phase-8.md +872 -872
  62. package/prompts/frontend/flow-build-phase-9.md +94 -94
  63. package/prompts/frontend/flow-build.md +137 -137
  64. package/prompts/frontend/flow-check-review.md +656 -20
  65. package/prompts/frontend/flow-check-test.md +526 -14
  66. package/prompts/frontend/flow-check.md +717 -67
  67. package/prompts/frontend/flow-commit.md +88 -119
  68. package/prompts/frontend/flow-docs-sync.md +550 -550
  69. package/prompts/frontend/flow-finish.md +919 -0
  70. package/prompts/frontend/flow-release.md +519 -0
  71. package/prompts/frontend/flow-work-api.md +1547 -0
  72. package/prompts/frontend/flow-work-feature.md +61 -61
  73. package/prompts/frontend/flow-work-fix.md +38 -38
  74. package/prompts/frontend/flow-work-refactor.md +48 -48
  75. package/prompts/frontend/flow-work-resume.md +34 -34
  76. package/prompts/frontend/flow-work.md +1595 -1320
  77. package/prompts/mobile/flow-build-phase-0.md +425 -425
  78. package/prompts/mobile/flow-build-phase-1.md +626 -626
  79. package/prompts/mobile/flow-build-phase-10.md +32 -32
  80. package/prompts/mobile/flow-build-phase-2.md +573 -573
  81. package/prompts/mobile/flow-build-phase-3.md +782 -782
  82. package/prompts/mobile/flow-build-phase-4.md +554 -554
  83. package/prompts/mobile/flow-build-phase-5.md +703 -703
  84. package/prompts/mobile/flow-build-phase-6.md +524 -524
  85. package/prompts/mobile/flow-build-phase-7.md +1001 -1001
  86. package/prompts/mobile/flow-build-phase-8.md +888 -888
  87. package/prompts/mobile/flow-build-phase-9.md +90 -90
  88. package/prompts/mobile/flow-build.md +135 -135
  89. package/prompts/mobile/flow-check-review.md +656 -20
  90. package/prompts/mobile/flow-check-test.md +526 -14
  91. package/prompts/mobile/flow-check.md +717 -67
  92. package/prompts/mobile/flow-commit.md +88 -119
  93. package/prompts/mobile/flow-docs-sync.md +620 -620
  94. package/prompts/mobile/flow-finish.md +919 -0
  95. package/prompts/mobile/flow-release.md +751 -0
  96. package/prompts/mobile/flow-work-api.md +1500 -0
  97. package/prompts/mobile/flow-work-feature.md +61 -61
  98. package/prompts/mobile/flow-work-fix.md +46 -46
  99. package/prompts/mobile/flow-work-refactor.md +48 -48
  100. package/prompts/mobile/flow-work-resume.md +34 -34
  101. package/prompts/mobile/flow-work.md +1605 -1329
  102. package/prompts/shared/mermaid-guidelines.md +102 -102
  103. package/prompts/shared/scope-levels.md +114 -114
  104. package/prompts/shared/smart-skip-preflight.md +214 -214
  105. package/prompts/shared/story-points.md +55 -55
  106. package/prompts/shared/task-format.md +74 -74
  107. package/prompts/shared/task-summary-template.md +277 -277
  108. package/templates/AGENT.template.md +443 -443
  109. package/templates/backend/.clauderules.template +112 -112
  110. package/templates/backend/.cursorrules.template +102 -102
  111. package/templates/backend/README.template.md +2 -2
  112. package/templates/backend/ai-instructions.template.md +2 -2
  113. package/templates/backend/copilot-instructions.template.md +2 -2
  114. package/templates/backend/docs/api.template.md +320 -320
  115. package/templates/backend/docs/business-flows.template.md +97 -97
  116. package/templates/backend/docs/code-standards.template.md +2 -2
  117. package/templates/backend/docs/contributing.template.md +3 -3
  118. package/templates/backend/docs/data-model.template.md +520 -520
  119. package/templates/backend/docs/testing.template.md +2 -2
  120. package/templates/backend/project-brief.template.md +2 -2
  121. package/templates/backend/specs/configuration.template.md +2 -2
  122. package/templates/backend/specs/security.template.md +2 -2
  123. package/templates/desktop/.clauderules.template +112 -112
  124. package/templates/desktop/.cursorrules.template +102 -102
  125. package/templates/desktop/README.template.md +170 -170
  126. package/templates/desktop/ai-instructions.template.md +366 -366
  127. package/templates/desktop/copilot-instructions.template.md +140 -140
  128. package/templates/desktop/docs/docs/api.template.md +320 -320
  129. package/templates/desktop/docs/docs/architecture.template.md +724 -724
  130. package/templates/desktop/docs/docs/business-flows.template.md +102 -102
  131. package/templates/desktop/docs/docs/code-standards.template.md +792 -792
  132. package/templates/desktop/docs/docs/contributing.template.md +149 -149
  133. package/templates/desktop/docs/docs/data-model.template.md +520 -520
  134. package/templates/desktop/docs/docs/operations.template.md +720 -720
  135. package/templates/desktop/docs/docs/testing.template.md +722 -722
  136. package/templates/desktop/project-brief.template.md +150 -150
  137. package/templates/desktop/specs/specs/configuration.template.md +121 -121
  138. package/templates/desktop/specs/specs/security.template.md +392 -392
  139. package/templates/frontend/README.template.md +2 -2
  140. package/templates/frontend/ai-instructions.template.md +2 -2
  141. package/templates/frontend/docs/api-integration.template.md +362 -362
  142. package/templates/frontend/docs/components.template.md +2 -2
  143. package/templates/frontend/docs/error-handling.template.md +360 -360
  144. package/templates/frontend/docs/operations.template.md +107 -107
  145. package/templates/frontend/docs/performance.template.md +124 -124
  146. package/templates/frontend/docs/pwa.template.md +119 -119
  147. package/templates/frontend/docs/state-management.template.md +2 -2
  148. package/templates/frontend/docs/styling.template.md +2 -2
  149. package/templates/frontend/docs/testing.template.md +2 -2
  150. package/templates/frontend/project-brief.template.md +2 -2
  151. package/templates/frontend/specs/accessibility.template.md +95 -95
  152. package/templates/frontend/specs/configuration.template.md +2 -2
  153. package/templates/frontend/specs/security.template.md +175 -175
  154. package/templates/fullstack/README.template.md +252 -252
  155. package/templates/fullstack/ai-instructions.template.md +444 -444
  156. package/templates/fullstack/project-brief.template.md +157 -157
  157. package/templates/fullstack/specs/configuration.template.md +340 -340
  158. package/templates/mobile/README.template.md +167 -167
  159. package/templates/mobile/ai-instructions.template.md +196 -196
  160. package/templates/mobile/docs/app-store.template.md +135 -135
  161. package/templates/mobile/docs/architecture.template.md +63 -63
  162. package/templates/mobile/docs/native-features.template.md +94 -94
  163. package/templates/mobile/docs/navigation.template.md +59 -59
  164. package/templates/mobile/docs/offline-strategy.template.md +65 -65
  165. package/templates/mobile/docs/permissions.template.md +56 -56
  166. package/templates/mobile/docs/state-management.template.md +85 -85
  167. package/templates/mobile/docs/testing.template.md +109 -109
  168. package/templates/mobile/project-brief.template.md +69 -69
  169. package/templates/mobile/specs/build-configuration.template.md +91 -91
  170. package/templates/mobile/specs/deployment.template.md +92 -92
  171. package/templates/work.template.md +61 -47
@@ -1,369 +1,369 @@
1
- # Error Handling
2
-
3
- > Error handling strategies and best practices for {{PROJECT_NAME}}
1
+ # Error Handling
2
+
3
+ > Error handling strategies and best practices for {{PROJECT_NAME}}
4
4
  ---
5
- ## 🎯 Error Handling Strategy
6
-
7
- **Approach:** {{ERROR_HANDLING_STRATEGY}}
8
- **Error Logging:** {{ERROR_LOGGING_TOOL}}
9
- **Recovery Strategy:** {{ERROR_RECOVERY_STRATEGY}}
5
+ ## 🎯 Error Handling Strategy
6
+
7
+ **Approach:** {{ERROR_HANDLING_STRATEGY}}
8
+ **Error Logging:** {{ERROR_LOGGING_TOOL}}
9
+ **Recovery Strategy:** {{ERROR_RECOVERY_STRATEGY}}
10
10
  ---
11
- ## 🛡️ Error Boundaries (React)
12
-
13
- ### Basic Error Boundary
14
-
15
- ```typescript
16
- // components/ErrorBoundary.tsx
17
- import React, { Component, ErrorInfo, ReactNode } from 'react';
18
-
19
- interface Props {
20
- children: ReactNode;
21
- fallback?: ReactNode;
22
- }
23
-
24
- interface State {
25
- hasError: boolean;
26
- error: Error | null;
27
- }
28
-
29
- export class ErrorBoundary extends Component<Props, State> {
30
- constructor(props: Props) {
31
- super(props);
32
- this.state = { hasError: false, error: null };
33
- }
34
-
35
- static getDerivedStateFromError(error: Error): State {
36
- return { hasError: true, error };
37
- }
38
-
39
- componentDidCatch(error: Error, errorInfo: ErrorInfo) {
40
- // Log error to error tracking service
41
- console.error('Error caught by boundary:', error, errorInfo);
42
-
43
- // Send to Sentry/LogRocket
44
- if (window.Sentry) {
45
- window.Sentry.captureException(error, { contexts: { react: errorInfo } });
46
- }
47
- }
48
-
49
- render() {
50
- if (this.state.hasError) {
51
- return this.props.fallback || (
52
- <div className="error-boundary">
53
- <h2>Something went wrong</h2>
54
- <button onClick={() => this.setState({ hasError: false, error: null })}>
55
- Try again
56
- </button>
57
- </div>
58
- );
59
- }
60
-
61
- return this.props.children;
62
- }
63
- }
64
- ```
65
-
66
- ### Usage
67
-
68
- ```typescript
69
- // App.tsx
70
- <ErrorBoundary fallback={<ErrorFallback />}>
71
- <App />
72
- </ErrorBoundary>
73
- ```
11
+ ## 🛡️ Error Boundaries (React)
12
+
13
+ ### Basic Error Boundary
14
+
15
+ ```typescript
16
+ // components/ErrorBoundary.tsx
17
+ import React, { Component, ErrorInfo, ReactNode } from 'react';
18
+
19
+ interface Props {
20
+ children: ReactNode;
21
+ fallback?: ReactNode;
22
+ }
23
+
24
+ interface State {
25
+ hasError: boolean;
26
+ error: Error | null;
27
+ }
28
+
29
+ export class ErrorBoundary extends Component<Props, State> {
30
+ constructor(props: Props) {
31
+ super(props);
32
+ this.state = { hasError: false, error: null };
33
+ }
34
+
35
+ static getDerivedStateFromError(error: Error): State {
36
+ return { hasError: true, error };
37
+ }
38
+
39
+ componentDidCatch(error: Error, errorInfo: ErrorInfo) {
40
+ // Log error to error tracking service
41
+ console.error('Error caught by boundary:', error, errorInfo);
42
+
43
+ // Send to Sentry/LogRocket
44
+ if (window.Sentry) {
45
+ window.Sentry.captureException(error, { contexts: { react: errorInfo } });
46
+ }
47
+ }
48
+
49
+ render() {
50
+ if (this.state.hasError) {
51
+ return this.props.fallback || (
52
+ <div className="error-boundary">
53
+ <h2>Something went wrong</h2>
54
+ <button onClick={() => this.setState({ hasError: false, error: null })}>
55
+ Try again
56
+ </button>
57
+ </div>
58
+ );
59
+ }
60
+
61
+ return this.props.children;
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### Usage
67
+
68
+ ```typescript
69
+ // App.tsx
70
+ <ErrorBoundary fallback={<ErrorFallback />}>
71
+ <App />
72
+ </ErrorBoundary>
73
+ ```
74
74
  ---
75
- ## 🔄 Global Error Handlers
76
-
77
- ### React Global Error Handler
78
-
79
- ```typescript
80
- // utils/globalErrorHandler.ts
81
- export function setupGlobalErrorHandler() {
82
- // Unhandled errors
83
- window.addEventListener('error', (event) => {
84
- console.error('Global error:', event.error);
85
- logError(event.error, { type: 'unhandled' });
86
- });
87
-
88
- // Unhandled promise rejections
89
- window.addEventListener('unhandledrejection', (event) => {
90
- console.error('Unhandled rejection:', event.reason);
91
- logError(event.reason, { type: 'unhandledRejection' });
92
- });
93
- }
94
- ```
95
-
96
- ### Vue Global Error Handler
97
-
98
- ```typescript
99
- // main.ts
100
- app.config.errorHandler = (err, instance, info) => {
101
- console.error('Vue error:', err, info);
102
- logError(err, { component: instance?.$options.name, info });
103
- };
104
- ```
105
-
106
- ### Angular Global Error Handler
107
-
108
- ```typescript
109
- // services/global-error-handler.service.ts
110
- @Injectable()
111
- export class GlobalErrorHandler implements ErrorHandler {
112
- constructor(private errorLoggingService: ErrorLoggingService) {}
113
-
114
- handleError(error: Error): void {
115
- console.error('Angular error:', error);
116
- this.errorLoggingService.logError(error);
117
- }
118
- }
119
- ```
75
+ ## 🔄 Global Error Handlers
76
+
77
+ ### React Global Error Handler
78
+
79
+ ```typescript
80
+ // utils/globalErrorHandler.ts
81
+ export function setupGlobalErrorHandler() {
82
+ // Unhandled errors
83
+ window.addEventListener('error', (event) => {
84
+ console.error('Global error:', event.error);
85
+ logError(event.error, { type: 'unhandled' });
86
+ });
87
+
88
+ // Unhandled promise rejections
89
+ window.addEventListener('unhandledrejection', (event) => {
90
+ console.error('Unhandled rejection:', event.reason);
91
+ logError(event.reason, { type: 'unhandledRejection' });
92
+ });
93
+ }
94
+ ```
95
+
96
+ ### Vue Global Error Handler
97
+
98
+ ```typescript
99
+ // main.ts
100
+ app.config.errorHandler = (err, instance, info) => {
101
+ console.error('Vue error:', err, info);
102
+ logError(err, { component: instance?.$options.name, info });
103
+ };
104
+ ```
105
+
106
+ ### Angular Global Error Handler
107
+
108
+ ```typescript
109
+ // services/global-error-handler.service.ts
110
+ @Injectable()
111
+ export class GlobalErrorHandler implements ErrorHandler {
112
+ constructor(private errorLoggingService: ErrorLoggingService) {}
113
+
114
+ handleError(error: Error): void {
115
+ console.error('Angular error:', error);
116
+ this.errorLoggingService.logError(error);
117
+ }
118
+ }
119
+ ```
120
120
  ---
121
- ## 📡 API Error Handling
122
-
123
- ### Error Types
124
-
125
- ```typescript
126
- // types/errors.ts
127
- export class ApiError extends Error {
128
- constructor(
129
- public status: number,
130
- public message: string,
131
- public code?: string,
132
- public details?: unknown
133
- ) {
134
- super(message);
135
- this.name = 'ApiError';
136
- }
137
- }
138
-
139
- export class NetworkError extends Error {
140
- constructor(message = 'Network error') {
141
- super(message);
142
- this.name = 'NetworkError';
143
- }
144
- }
145
-
146
- export class TimeoutError extends Error {
147
- constructor(message = 'Request timeout') {
148
- super(message);
149
- this.name = 'TimeoutError';
150
- }
151
- }
152
- ```
153
-
154
- ### Error Handling by Status Code
155
-
156
- ```typescript
157
- // utils/apiErrorHandler.ts
158
- export function handleApiError(error: unknown): {
159
- message: string;
160
- action: 'retry' | 'redirect' | 'show' | 'ignore';
161
- } {
162
- if (error instanceof ApiError) {
163
- switch (error.status) {
164
- case 400:
165
- return {
166
- message: 'Invalid request. Please check your input.',
167
- action: 'show',
168
- };
169
- case 401:
170
- return {
171
- message: 'Session expired. Please log in again.',
172
- action: 'redirect', // Redirect to login
173
- };
174
- case 403:
175
- return {
176
- message: 'Access denied.',
177
- action: 'show',
178
- };
179
- case 404:
180
- return {
181
- message: 'Resource not found.',
182
- action: 'show',
183
- };
184
- case 429:
185
- return {
186
- message: 'Too many requests. Please try again later.',
187
- action: 'retry',
188
- };
189
- case 500:
190
- case 502:
191
- case 503:
192
- case 504:
193
- return {
194
- message: 'Server error. Please try again.',
195
- action: 'retry',
196
- };
197
- default:
198
- return {
199
- message: 'An error occurred. Please try again.',
200
- action: 'show',
201
- };
202
- }
203
- }
204
-
205
- if (error instanceof NetworkError) {
206
- return {
207
- message: 'Network error. Please check your connection.',
208
- action: 'retry',
209
- };
210
- }
211
-
212
- if (error instanceof TimeoutError) {
213
- return {
214
- message: 'Request timed out. Please try again.',
215
- action: 'retry',
216
- };
217
- }
218
-
219
- return {
220
- message: 'An unexpected error occurred.',
221
- action: 'show',
222
- };
223
- }
224
- ```
121
+ ## 📡 API Error Handling
122
+
123
+ ### Error Types
124
+
125
+ ```typescript
126
+ // types/errors.ts
127
+ export class ApiError extends Error {
128
+ constructor(
129
+ public status: number,
130
+ public message: string,
131
+ public code?: string,
132
+ public details?: unknown
133
+ ) {
134
+ super(message);
135
+ this.name = 'ApiError';
136
+ }
137
+ }
138
+
139
+ export class NetworkError extends Error {
140
+ constructor(message = 'Network error') {
141
+ super(message);
142
+ this.name = 'NetworkError';
143
+ }
144
+ }
145
+
146
+ export class TimeoutError extends Error {
147
+ constructor(message = 'Request timeout') {
148
+ super(message);
149
+ this.name = 'TimeoutError';
150
+ }
151
+ }
152
+ ```
153
+
154
+ ### Error Handling by Status Code
155
+
156
+ ```typescript
157
+ // utils/apiErrorHandler.ts
158
+ export function handleApiError(error: unknown): {
159
+ message: string;
160
+ action: 'retry' | 'redirect' | 'show' | 'ignore';
161
+ } {
162
+ if (error instanceof ApiError) {
163
+ switch (error.status) {
164
+ case 400:
165
+ return {
166
+ message: 'Invalid request. Please check your input.',
167
+ action: 'show',
168
+ };
169
+ case 401:
170
+ return {
171
+ message: 'Session expired. Please log in again.',
172
+ action: 'redirect', // Redirect to login
173
+ };
174
+ case 403:
175
+ return {
176
+ message: 'Access denied.',
177
+ action: 'show',
178
+ };
179
+ case 404:
180
+ return {
181
+ message: 'Resource not found.',
182
+ action: 'show',
183
+ };
184
+ case 429:
185
+ return {
186
+ message: 'Too many requests. Please try again later.',
187
+ action: 'retry',
188
+ };
189
+ case 500:
190
+ case 502:
191
+ case 503:
192
+ case 504:
193
+ return {
194
+ message: 'Server error. Please try again.',
195
+ action: 'retry',
196
+ };
197
+ default:
198
+ return {
199
+ message: 'An error occurred. Please try again.',
200
+ action: 'show',
201
+ };
202
+ }
203
+ }
204
+
205
+ if (error instanceof NetworkError) {
206
+ return {
207
+ message: 'Network error. Please check your connection.',
208
+ action: 'retry',
209
+ };
210
+ }
211
+
212
+ if (error instanceof TimeoutError) {
213
+ return {
214
+ message: 'Request timed out. Please try again.',
215
+ action: 'retry',
216
+ };
217
+ }
218
+
219
+ return {
220
+ message: 'An unexpected error occurred.',
221
+ action: 'show',
222
+ };
223
+ }
224
+ ```
225
225
  ---
226
- ## 🔁 Retry Logic
227
-
228
- ### Exponential Backoff Retry
229
-
230
- ```typescript
231
- // utils/retry.ts
232
- export async function retryWithBackoff<T>(
233
- fn: () => Promise<T>,
234
- maxRetries = 3,
235
- initialDelay = 1000
236
- ): Promise<T> {
237
- for (let attempt = 0; attempt < maxRetries; attempt++) {
238
- try {
239
- return await fn();
240
- } catch (error) {
241
- if (attempt === maxRetries - 1) throw error;
242
-
243
- // Don't retry on 4xx errors (except 429)
244
- if (error instanceof ApiError && error.status >= 400 && error.status < 500 && error.status !== 429) {
245
- throw error;
246
- }
247
-
248
- // Exponential backoff: 1s, 2s, 4s
249
- const delay = initialDelay * Math.pow(2, attempt);
250
- await new Promise(resolve => setTimeout(resolve, delay));
251
- }
252
- }
253
- throw new Error('Max retries exceeded');
254
- }
255
- ```
256
-
257
- ### Usage with TanStack Query
258
-
259
- ```typescript
260
- import { useQuery } from '@tanstack/react-query';
261
-
262
- const { data } = useQuery({
263
- queryKey: ['users', id],
264
- queryFn: () => usersService.getById(id),
265
- retry: (failureCount, error) => {
266
- // Don't retry on 4xx errors
267
- if (error instanceof ApiError && error.status >= 400 && error.status < 500) {
268
- return false;
269
- }
270
- return failureCount < 3;
271
- },
272
- retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
273
- });
274
- ```
226
+ ## 🔁 Retry Logic
227
+
228
+ ### Exponential Backoff Retry
229
+
230
+ ```typescript
231
+ // utils/retry.ts
232
+ export async function retryWithBackoff<T>(
233
+ fn: () => Promise<T>,
234
+ maxRetries = 3,
235
+ initialDelay = 1000
236
+ ): Promise<T> {
237
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
238
+ try {
239
+ return await fn();
240
+ } catch (error) {
241
+ if (attempt === maxRetries - 1) throw error;
242
+
243
+ // Don't retry on 4xx errors (except 429)
244
+ if (error instanceof ApiError && error.status >= 400 && error.status < 500 && error.status !== 429) {
245
+ throw error;
246
+ }
247
+
248
+ // Exponential backoff: 1s, 2s, 4s
249
+ const delay = initialDelay * Math.pow(2, attempt);
250
+ await new Promise(resolve => setTimeout(resolve, delay));
251
+ }
252
+ }
253
+ throw new Error('Max retries exceeded');
254
+ }
255
+ ```
256
+
257
+ ### Usage with TanStack Query
258
+
259
+ ```typescript
260
+ import { useQuery } from '@tanstack/react-query';
261
+
262
+ const { data } = useQuery({
263
+ queryKey: ['users', id],
264
+ queryFn: () => usersService.getById(id),
265
+ retry: (failureCount, error) => {
266
+ // Don't retry on 4xx errors
267
+ if (error instanceof ApiError && error.status >= 400 && error.status < 500) {
268
+ return false;
269
+ }
270
+ return failureCount < 3;
271
+ },
272
+ retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
273
+ });
274
+ ```
275
275
  ---
276
- ## 📝 Error Logging
277
-
278
- ### Error Logging Service
279
-
280
- ```typescript
281
- // services/errorLogging.ts
282
- import * as Sentry from '@sentry/react';
283
-
284
- export function logError(error: Error, context?: Record<string, unknown>) {
285
- // Development: Console
286
- if (import.meta.env.DEV) {
287
- console.error('Error:', error, context);
288
- return;
289
- }
290
-
291
- // Production: Sentry
292
- Sentry.captureException(error, {
293
- contexts: {
294
- custom: context || {},
295
- },
296
- tags: {
297
- component: context?.component as string,
298
- },
299
- });
300
- }
301
- ```
302
-
303
- ### User Context
304
-
305
- ```typescript
306
- // Add user context to errors
307
- Sentry.setUser({
308
- id: user.id,
309
- email: user.email,
310
- username: user.username,
311
- });
312
- ```
276
+ ## 📝 Error Logging
277
+
278
+ ### Error Logging Service
279
+
280
+ ```typescript
281
+ // services/errorLogging.ts
282
+ import * as Sentry from '@sentry/react';
283
+
284
+ export function logError(error: Error, context?: Record<string, unknown>) {
285
+ // Development: Console
286
+ if (import.meta.env.DEV) {
287
+ console.error('Error:', error, context);
288
+ return;
289
+ }
290
+
291
+ // Production: Sentry
292
+ Sentry.captureException(error, {
293
+ contexts: {
294
+ custom: context || {},
295
+ },
296
+ tags: {
297
+ component: context?.component as string,
298
+ },
299
+ });
300
+ }
301
+ ```
302
+
303
+ ### User Context
304
+
305
+ ```typescript
306
+ // Add user context to errors
307
+ Sentry.setUser({
308
+ id: user.id,
309
+ email: user.email,
310
+ username: user.username,
311
+ });
312
+ ```
313
313
  ---
314
- ## 🎨 Error UI Components
315
-
316
- ### Error Display Component
317
-
318
- ```typescript
319
- // components/ErrorDisplay.tsx
320
- interface ErrorDisplayProps {
321
- error: Error;
322
- onRetry?: () => void;
323
- }
324
-
325
- export const ErrorDisplay: React.FC<ErrorDisplayProps> = ({ error, onRetry }) => {
326
- const { message, action } = handleApiError(error);
327
-
328
- return (
329
- <div className="error-display">
330
- <h3>Oops! Something went wrong</h3>
331
- <p>{message}</p>
332
- {action === 'retry' && onRetry && (
333
- <button onClick={onRetry}>Try Again</button>
334
- )}
335
- </div>
336
- );
337
- };
338
- ```
339
-
340
- ### Fallback UI
341
-
342
- ```typescript
343
- // components/ErrorFallback.tsx
344
- export const ErrorFallback: React.FC<{ error: Error; resetError: () => void }> = ({
345
- error,
346
- resetError,
347
- }) => {
348
- return (
349
- <div className="error-fallback">
350
- <h2>Something went wrong</h2>
351
- <pre>{error.message}</pre>
352
- <button onClick={resetError}>Try again</button>
353
- </div>
354
- );
355
- };
356
- ```
314
+ ## 🎨 Error UI Components
315
+
316
+ ### Error Display Component
317
+
318
+ ```typescript
319
+ // components/ErrorDisplay.tsx
320
+ interface ErrorDisplayProps {
321
+ error: Error;
322
+ onRetry?: () => void;
323
+ }
324
+
325
+ export const ErrorDisplay: React.FC<ErrorDisplayProps> = ({ error, onRetry }) => {
326
+ const { message, action } = handleApiError(error);
327
+
328
+ return (
329
+ <div className="error-display">
330
+ <h3>Oops! Something went wrong</h3>
331
+ <p>{message}</p>
332
+ {action === 'retry' && onRetry && (
333
+ <button onClick={onRetry}>Try Again</button>
334
+ )}
335
+ </div>
336
+ );
337
+ };
338
+ ```
339
+
340
+ ### Fallback UI
341
+
342
+ ```typescript
343
+ // components/ErrorFallback.tsx
344
+ export const ErrorFallback: React.FC<{ error: Error; resetError: () => void }> = ({
345
+ error,
346
+ resetError,
347
+ }) => {
348
+ return (
349
+ <div className="error-fallback">
350
+ <h2>Something went wrong</h2>
351
+ <pre>{error.message}</pre>
352
+ <button onClick={resetError}>Try again</button>
353
+ </div>
354
+ );
355
+ };
356
+ ```
357
357
  ---
358
- ## 🔗 Related Documents
359
-
360
- - [API Integration](api-integration.md) - API error handling
361
- - [State Management](state-management.md) - Error state management
362
- - [Security](security.md) - Security error handling
358
+ ## 🔗 Related Documents
359
+
360
+ - [API Integration](api-integration.md) - API error handling
361
+ - [State Management](state-management.md) - Error state management
362
+ - [Security](security.md) - Security error handling
363
363
  ---
364
- **Last Updated:** {{GENERATION_DATE}}
365
-
366
- **Error Handling Strategy:** {{ERROR_HANDLING_STRATEGY}}
367
-
368
-
369
-
364
+ **Last Updated:** {{GENERATION_DATE}}
365
+
366
+ **Error Handling Strategy:** {{ERROR_HANDLING_STRATEGY}}
367
+
368
+
369
+