Skip to content

Commit 67cdc64

Browse files
feat(ErrorBoundary): add theme-aware colors and component stack to error details
Signed-off-by: Harshit Kumar <10harshitkumar@gmail.com>
1 parent a4b8003 commit 67cdc64

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

src/components/ErrorBoundary.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Component, ErrorInfo, ReactNode } from 'react';
2+
import useAppStore from '../store/store';
23

34
interface Props {
45
children: ReactNode;
@@ -7,24 +8,30 @@ interface Props {
78
interface State {
89
hasError: boolean;
910
error: Error | null;
11+
errorInfo: ErrorInfo | null;
1012
}
1113

1214
class ErrorBoundary extends Component<Props, State> {
1315
constructor(props: Props) {
1416
super(props);
15-
this.state = { hasError: false, error: null };
17+
this.state = { hasError: false, error: null, errorInfo: null };
1618
}
1719

1820
static getDerivedStateFromError(error: Error): State {
19-
return { hasError: true, error };
21+
return { hasError: true, error, errorInfo: null };
2022
}
2123

2224
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
2325
console.error('ErrorBoundary caught an error:', error, errorInfo);
26+
this.setState({ errorInfo });
2427
}
2528

2629
render() {
2730
if (this.state.hasError) {
31+
// Get theme colors from store
32+
const { backgroundColor, textColor } = useAppStore.getState();
33+
const isDarkMode = backgroundColor === '#1e1e1e';
34+
2835
return (
2936
<div style={{
3037
display: 'flex',
@@ -34,12 +41,12 @@ class ErrorBoundary extends Component<Props, State> {
3441
height: '100vh',
3542
padding: '2rem',
3643
textAlign: 'center',
37-
backgroundColor: '#f5f5f5'
44+
backgroundColor: backgroundColor
3845
}}>
3946
<h1 style={{ fontSize: '2rem', marginBottom: '1rem', color: '#d32f2f' }}>
4047
Something went wrong
4148
</h1>
42-
<p style={{ fontSize: '1rem', marginBottom: '2rem', color: '#666', maxWidth: '600px' }}>
49+
<p style={{ fontSize: '1rem', marginBottom: '2rem', color: textColor, maxWidth: '600px', opacity: 0.8 }}>
4350
We apologize for the inconvenience. An unexpected error has occurred.
4451
</p>
4552
<button
@@ -59,19 +66,26 @@ class ErrorBoundary extends Component<Props, State> {
5966
</button>
6067
{this.state.error && import.meta.env.DEV && (
6168
<details style={{ marginTop: '2rem', maxWidth: '800px', textAlign: 'left' }}>
62-
<summary style={{ cursor: 'pointer', color: '#666', fontSize: '0.9rem' }}>
69+
<summary style={{ cursor: 'pointer', color: textColor, opacity: 0.8, fontSize: '0.9rem' }}>
6370
Error details
6471
</summary>
6572
<pre style={{
6673
marginTop: '1rem',
6774
padding: '1rem',
68-
backgroundColor: '#fff',
69-
border: '1px solid #ddd',
75+
backgroundColor: isDarkMode ? '#2d2d2d' : '#fff',
76+
color: textColor,
77+
border: `1px solid ${isDarkMode ? '#444' : '#ddd'}`,
7078
borderRadius: '4px',
7179
overflow: 'auto',
7280
fontSize: '0.85rem'
7381
}}>
7482
{this.state.error.toString()}
83+
{this.state.errorInfo?.componentStack && (
84+
<>
85+
{'\n\nComponent Stack:'}
86+
{this.state.errorInfo.componentStack}
87+
</>
88+
)}
7589
</pre>
7690
</details>
7791
)}

src/tests/components/ErrorBoundary.test.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { render, screen } from "@testing-library/react";
22
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
33
import "@testing-library/jest-dom";
44
import ErrorBoundary from "../../components/ErrorBoundary";
5+
import useAppStore from "../../store/store";
56

67
// Component that throws an error for testing
78
const ThrowError = ({ shouldThrow }: { shouldThrow: boolean }) => {
@@ -113,4 +114,35 @@ describe("ErrorBoundary", () => {
113114
expect.any(Object)
114115
);
115116
});
117+
118+
it("should use theme colors from store", () => {
119+
// Set dark mode
120+
useAppStore.setState({ backgroundColor: '#1e1e1e', textColor: '#ffffff' });
121+
122+
render(
123+
<ErrorBoundary>
124+
<ThrowError shouldThrow={true} />
125+
</ErrorBoundary>
126+
);
127+
128+
const container = screen.getByText("Something went wrong").parentElement;
129+
expect(container).toHaveStyle({ backgroundColor: '#1e1e1e' });
130+
});
131+
132+
it("should display component stack in development mode", () => {
133+
import.meta.env.DEV = true;
134+
135+
render(
136+
<ErrorBoundary>
137+
<ThrowError shouldThrow={true} />
138+
</ErrorBoundary>
139+
);
140+
141+
const errorDetails = screen.getByText("Error details");
142+
expect(errorDetails).toBeInTheDocument();
143+
144+
// Component stack should be present in the pre element
145+
const preElement = screen.getByText(/Error: Test error/).closest('pre');
146+
expect(preElement?.textContent).toContain('Component Stack:');
147+
});
116148
});

0 commit comments

Comments
 (0)