π¨ Anatomy of a 3 AM Production Crisis: A Testing Tale
π The Scene:
// The innocent-looking code that ruined everyone's night
const getDomainUrl = (config: BackendConfig) => {
return config.domain; // What could go wrong? Everything.
};
π Let's Debug Together: The Case of the Phantom Redirect
π¨ The Crime Scene
Dashboard users land at
undefined/rest-path
after a "harmless" config change
- Suspect: A sneaky backend configuration tweak
- Weapon: Missing validation for domain paths
- Motive: "It worked in dev!" π€¦
Unit testing
describe('Domain Configuration', () => {
it('should reject missing domain configuration', () => {
const emptyConfig = {} as BackendConfig;
expect(() => getDomainUrl(emptyConfig)).toThrow();
});
});
Code
const getDomainUrl = (config: BackendConfig): string => {
if (!config.domain) {
throw new DomainConfigError('Domain URL is required');
}
if (!isValidDomainUrl(config.domain)) {
throw new DomainConfigError('Invalid domain URL format');
}
return config.domain;
};
Component Testing
describe('RedirectHandler', () => {
it('should handle domain configuration gracefully', () => {
const mockConfig = {};
const { getByTestId } = render(<RedirectHandler config={mockConfig} />);
expect(getByTestId('config-error')).toBeInTheDocument();
expect(captureError).toHaveBeenCalledWith(expect.any(DomainConfigError));
});
});
Code
const RedirectHandler: React.FC<{ config: BackendConfig }> = ({ config }) => {
const [error, setError] = useState<string>();
const navigate = useNavigate();
useEffect(() => {
try {
const domainUrl = getDomainUrl(config);
// Safely handle navigation
navigate(`${domainUrl}/rest-path`);
} catch (e) {
if (e instanceof DomainConfigError) {
setError(e.message);
// Log to monitoring system
captureError(e);
}
}
}, [config, navigate]);
if (error) {
return (
<ErrorBoundary>
<ConfigurationError
message={error}
retry={() => window.location.reload()}
/>
</ErrorBoundary>
);
}
return <LoadingSpinner />;
};
π οΈ The Evolution of Robust Domain Configuration
π― What Changed?
-
Prevention Layers:
- π‘οΈ Custom error types (
InvalidDomainException
) - π Domain validation before redirect logic
- π¨ Error boundaries to catch misconfigurations
- π‘οΈ Custom error types (
-
Test-First Approach:
- π§ͺ Wrote failing test for missing config first
- β Added domain validation logic
- π₯ Simulated edge cases (malformed URLs, empty configs)
-
Better Error UX:
- π’ User-friendly message: "Oops! We hit a snag β try again?"
- π Retry button with auto-logging for engineers
- π Integrated error tracking (Sentry/Datadog)
π The Results
- β No more undefined redirects
- π Clear error tracking
- π΄ Happy users (and developers who can sleep at night!)
π― The Tale of Two Developers: TDD vs. "We'll Test Later"
π Bugs Bunny (Traditional):
- π₯ 3 AM: Debugging while production burns
- π Result: Chasing midnight bugs, endless firefighting
β Iron Man (TDD):
"Test first, code with confidence."
- π Result: Deploys and sleeps soundly
- π‘οΈ Secret Weapon: Tests act as code armor
π The Real Difference:
Same deadline, drastically different outcomes.
While Bugs Bunny chases production bugs at midnight, Iron Manβs approach means:
π‘οΈ Prevention > Cure
- Catches bugs before they reach production
- Each test is a shield against future issues
- No more 3 AM emergency fixes
π― Design That Makes Sense
- Tests force you to think before coding
- Code becomes naturally modular
- Refactoring becomes a breeze
π Code That Tells a Story
- Tests document how things should work
- New team members get up to speed faster
- Requirements are crystal clear
Top comments (0)