• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

agentic-dev-library / thumbcode / 21119387846

18 Jan 2026 10:06PM UTC coverage: 25.529% (+3.7%) from 21.828%
21119387846

push

github

web-flow
feat(error): implement comprehensive error handling and logging system (#52)

* feat(error): implement comprehensive error handling and logging system

- Add production-grade logging service with levels (debug, info, warn, error, fatal)
- Add Logger class with context enrichment and optional remote logging
- Create ErrorBoundary component for catching React errors
- Create ErrorFallback component with organic design styling
- Add CompactErrorFallback for inline error display
- Implement global error handler with standardized AppError type
- Add error codes and user-friendly error messages
- Create retry utility with exponential backoff and jitter
- Add retry presets (quick, standard, patient, aggressive)
- Implement useNetworkError hook for network status monitoring
- Implement useIsOnline hook for simple connectivity checks
- Integrate ErrorBoundary in root layout
- Initialize global error handlers on app start

Closes #16

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

* test(error): add comprehensive tests for error handling utilities

- Add tests for Logger class (log levels, filtering, context, buffering)
- Add tests for error handler (createAppError, parseError, handleError)
- Add tests for retry utility (retry, withRetry, presets, error detection)
- Increases test coverage from ~5% to ~34%

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

* fix(error): address CodeRabbit review feedback

- Add onPress handler to Report Issue button in ErrorFallback
- Add onReportIssue prop for custom report handling
- Fix stale closure in useNetworkError by using ref for previous state
- Validate maxAttempts in retry function (normalize to at least 1)
- Initialize lastError to avoid throwing undefined
- Remove unused type import in error-handler tests

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

260 of 1612 branches covered (16.13%)

Branch coverage included in aggregate %.

126 of 220 new or added lines in 7 files covered. (57.27%)

621 of 1839 relevant lines covered (33.77%)

1.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/components/error/ErrorFallback.tsx
1
/**
2
 * Error Fallback Component
3
 *
4
 * User-friendly error display with retry functionality.
5
 * Follows ThumbCode's organic design language.
6
 */
7

8
import { Alert, Pressable, View } from 'react-native';
9
import { useSafeAreaInsets } from 'react-native-safe-area-context';
10
import { Container, VStack } from '@/components/layout';
11
import { Text } from '@/components/ui';
12

13
interface ErrorFallbackProps {
14
  error: Error | null;
15
  componentStack?: string | null;
16
  onRetry?: () => void;
17
  onReportIssue?: () => void;
18
  title?: string;
19
  message?: string;
20
}
21

22
export function ErrorFallback({
23
  error,
24
  componentStack,
25
  onRetry,
26
  onReportIssue,
27
  title = 'Something went wrong',
×
28
  message = "We're sorry, but something unexpected happened. Please try again.",
×
29
}: ErrorFallbackProps) {
NEW
30
  const insets = useSafeAreaInsets();
×
NEW
31
  const isDev = __DEV__;
×
32

NEW
33
  const handleReportIssue = () => {
×
NEW
34
    if (onReportIssue) {
×
NEW
35
      onReportIssue();
×
36
    } else {
37
      // TODO: Implement proper issue reporting (e.g., open GitHub issues URL)
NEW
38
      Alert.alert('Report Issue', 'Issue reporting will be available in a future update.');
×
39
    }
40
  };
41

NEW
42
  return (
×
43
    <View
44
      className="flex-1 bg-charcoal"
45
      style={{ paddingTop: insets.top, paddingBottom: insets.bottom }}
46
    >
47
      <Container padding="lg" className="flex-1 justify-center">
48
        <VStack spacing="lg" align="center">
49
          {/* Error Icon */}
50
          <View
51
            className="w-20 h-20 bg-coral-500/20 items-center justify-center"
52
            style={{
53
              borderTopLeftRadius: 40,
54
              borderTopRightRadius: 36,
55
              borderBottomRightRadius: 42,
56
              borderBottomLeftRadius: 38,
57
            }}
58
          >
59
            <Text className="text-4xl">⚠️</Text>
60
          </View>
61

62
          {/* Error Title */}
63
          <Text size="xl" weight="bold" className="text-white text-center font-display">
64
            {title}
65
          </Text>
66

67
          {/* Error Message */}
68
          <Text className="text-neutral-400 text-center max-w-xs">{message}</Text>
69

70
          {/* Dev-only Error Details */}
71
          {isDev && error && (
×
72
            <View
73
              className="bg-surface p-4 w-full max-w-sm"
74
              style={{
75
                borderTopLeftRadius: 12,
76
                borderTopRightRadius: 10,
77
                borderBottomRightRadius: 14,
78
                borderBottomLeftRadius: 8,
79
              }}
80
            >
81
              <Text size="sm" weight="semibold" className="text-coral-500 mb-2">
82
                Debug Info
83
              </Text>
84
              <Text size="sm" className="text-neutral-400 font-mono mb-2">
85
                {error.name}: {error.message}
86
              </Text>
87
              {componentStack && (
×
88
                <Text size="xs" className="text-neutral-500 font-mono" numberOfLines={8}>
89
                  {componentStack}
90
                </Text>
91
              )}
92
            </View>
93
          )}
94

95
          {/* Retry Button */}
96
          {onRetry && (
×
97
            <Pressable
98
              onPress={onRetry}
99
              className="bg-coral-500 px-8 py-3 active:bg-coral-600"
100
              style={{
101
                borderTopLeftRadius: 24,
102
                borderTopRightRadius: 22,
103
                borderBottomRightRadius: 26,
104
                borderBottomLeftRadius: 20,
105
              }}
106
            >
107
              <Text weight="semibold" className="text-white">
108
                Try Again
109
              </Text>
110
            </Pressable>
111
          )}
112

113
          {/* Secondary Action */}
114
          <Pressable className="py-2" onPress={handleReportIssue}>
115
            <Text size="sm" className="text-teal-500">
116
              Report Issue
117
            </Text>
118
          </Pressable>
119
        </VStack>
120
      </Container>
121
    </View>
122
  );
123
}
124

125
/**
126
 * Compact error fallback for inline use
127
 */
128
interface CompactErrorFallbackProps {
129
  message?: string;
130
  onRetry?: () => void;
131
}
132

133
export function CompactErrorFallback({
134
  message = 'Failed to load',
×
135
  onRetry,
136
}: CompactErrorFallbackProps) {
NEW
137
  return (
×
138
    <View
139
      className="bg-surface/50 p-4"
140
      style={{
141
        borderTopLeftRadius: 12,
142
        borderTopRightRadius: 10,
143
        borderBottomRightRadius: 14,
144
        borderBottomLeftRadius: 8,
145
      }}
146
    >
147
      <VStack spacing="sm" align="center">
148
        <Text size="sm" className="text-neutral-400">
149
          {message}
150
        </Text>
151
        {onRetry && (
×
152
          <Pressable onPress={onRetry}>
153
            <Text size="sm" className="text-teal-500">
154
              Tap to retry
155
            </Text>
156
          </Pressable>
157
        )}
158
      </VStack>
159
    </View>
160
  );
161
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc