try-error Documentation
Migration Guide
Gradually adopt try-error in your existing codebase
Progressive Adoption
try-error is designed for gradual adoption. You can start using it in new code while keeping existing try/catch blocks unchanged.
✅ Safe Migration: try-error works alongside traditional error handling. No need for a big rewrite!
Before and After
Synchronous Operations
❌ Before (try/catch)
function parseConfig(jsonString: string) {
try {
const config = JSON.parse(jsonString);
return config;
} catch (error) {
console.error('Parse failed:', error);
return null;
}
}
✅ After (try-error)
function parseConfig(jsonString: string) {
const result = trySync(() => JSON.parse(jsonString));
if (isTryError(result)) {
console.error('Parse failed:', result.message);
return null;
}
return result;
}
Asynchronous Operations
❌ Before (try/catch)
async function fetchUser(id: string) {
try {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
return user;
} catch (error) {
console.error('Fetch failed:', error);
throw error;
}
}
✅ After (try-error)
async function fetchUser(id: string) {
const response = await tryAsync(() =>
fetch(`/api/users/${id}`)
);
if (isTryError(response)) {
console.error('Fetch failed:', response.message);
return response; // Return the error
}
const user = await tryAsync(() => response.json());
return user; // Could be success or error
}
Migration Strategies
1. Start with New Code
Begin using try-error for all new functions and modules. This gives you immediate benefits without touching existing code.
2. Migrate Utility Functions
Convert small utility functions first. These are usually easier to test and have fewer dependencies.
// Easy migration target
function safeParseInt(value: string) {
const result = trySync(() => {
const num = parseInt(value, 10);
if (isNaN(num)) throw new Error('Not a valid number');
return num;
});
return isTryError(result) ? 0 : result;
}
3. Migrate API Boundaries
Convert functions that interact with external APIs, databases, or file systems. These benefit most from explicit error handling.
4. Gradual Refactoring
When you need to modify existing functions, consider converting them to try-error at the same time.
Interoperability
try-error functions can easily work with traditional try/catch code:
1// try-error function called from try/catch code
2function legacyFunction() {
3 try {
4 const result = newTryErrorFunction();
5 if (isTryError(result)) {
6 throw new Error(result.message);
7 }
8 return result;
9 } catch (error) {
10 console.error('Legacy error handling:', error);
11 throw error;
12 }
13}
14
15// try/catch function called from try-error code
16async function newFunction() {
17 const result = await tryAsync(() => legacyAsyncFunction());
18 if (isTryError(result)) {
19 console.error('Legacy function failed:', result.message);
20 return null;
21 }
22 return result;
23}
Common Migration Patterns
Error Propagation
Before
async function processData() {
try {
const data = await fetchData();
const processed = await processStep1(data);
const result = await processStep2(processed);
return result;
} catch (error) {
throw error; // Re-throw
}
}
After
async function processData() {
const data = await tryAsync(() => fetchData());
if (isTryError(data)) return data;
const processed = await tryAsync(() => processStep1(data));
if (isTryError(processed)) return processed;
const result = await tryAsync(() => processStep2(processed));
return result; // Success or error
}
Default Values
Before
function getConfig() {
try {
return JSON.parse(configString);
} catch {
return defaultConfig;
}
}
After
function getConfig() {
const result = trySync(() => JSON.parse(configString));
return isTryError(result) ? defaultConfig : result;
}
Testing During Migration
Your existing tests should continue to work. For new try-error code, test both success and error cases:
1describe('parseConfig', () => {
2 it('should parse valid JSON', () => {
3 const result = parseConfig('{"key": "value"}');
4 expect(isTryError(result)).toBe(false);
5 if (!isTryError(result)) {
6 expect(result.key).toBe('value');
7 }
8 });
9
10 it('should handle invalid JSON', () => {
11 const result = parseConfig('invalid json');
12 expect(isTryError(result)).toBe(true);
13 if (isTryError(result)) {
14 expect(result.message).toContain('JSON');
15 }
16 });
17});