Error Propagation
Examples of error propagation patterns in go-errors
Error Propagation
This page demonstrates various patterns for propagating errors in go-errors.
Basic Error Propagation
import { goSync } from 'go-errors';
function step1() {
let [result, err] = goSync(() => {
// Some operation that might fail
if (Math.random() < 0.5) throw new Error('Step 1 failed');
return 'Step 1 success';
});
if (err) return [null, err] as const;
return [result, null] as const;
}
function step2(input: string) {
let [result, err] = goSync(() => {
// Another operation that might fail
if (Math.random() < 0.5) throw new Error('Step 2 failed');
return `${input} -> Step 2 success`;
});
if (err) return [null, err] as const;
return [result, null] as const;
}
async function process() {
let [step1Result, err] = step1();
if (err) return [null, err] as const;
let [step2Result, err] = step2(step1Result);
if (err) return [null, err] as const;
return [step2Result, null] as const;
}
Error Context Preservation
import { goSync } from 'go-errors';
class ValidationError extends Error {
constructor(message: string, public field: string) {
super(message);
this.name = 'ValidationError';
}
}
function validateEmail(email: string) {
let [result, err] = goSync(() => {
if (!email.includes('@')) {
throw new ValidationError('Invalid email format', 'email');
}
return email;
});
if (err) {
// Add more context to the error
return [null, new Error(`Email validation failed: ${err.message}`, { cause: err })] as const;
}
return [result, null] as const;
}
function validateUser(user: { email: string }) {
let [email, err] = validateEmail(user.email);
if (err) {
// Propagate with additional context
return [null, new Error('User validation failed', { cause: err })] as const;
}
return [{ ...user, email }, null] as const;
}
HTTP Error Propagation
import { goFetch } from 'go-errors';
interface ApiError {
code: string;
message: string;
details?: string;
}
interface User {
id: number;
firstName: string;
lastName: string;
fullName: string;
email: string;
}
async function fetchUserData(userId: string) {
let [user, err] = await goFetch<User, ApiError>(`/api/users/${userId}`, {
responseTransformer: (data) => ({
...data,
fullName: `${data.firstName} ${data.lastName}`
}),
errorTransformer: (error) => {
if (error instanceof Response) {
return {
code: `HTTP_${error.status}`,
message: error.statusText
};
}
return {
code: 'UNKNOWN_ERROR',
message: error instanceof Error ? error.message : 'Unknown error'
};
}
});
if (err) {
return [null, new Error(`Failed to fetch user data: ${err.message}`, { cause: err })] as const;
}
return [user, null] as const;
}
async function processUserData(userId: string) {
let [user, err] = await fetchUserData(userId);
if (err) {
return [null, new Error('User data processing failed', { cause: err })] as const;
}
let [validatedData, err] = goSync(() => validateUserData(user));
if (err) {
return [null, new Error('User data validation failed', { cause: err })] as const;
}
return [validatedData, null] as const;
}
API Client Error Handling
import { goFetch } from 'go-errors';
class ApiClient {
constructor(private baseUrl: string, private token: string) {}
private async request<T>(endpoint: string) {
let [response, err] = await goFetch<T>(`${this.baseUrl}${endpoint}`, {
headers: {
'Authorization': `Bearer ${this.token}`
},
errorTransformer: (error) => {
if (error instanceof Response) {
return new ApiError(`HTTP_${error.status}`, error.statusText);
}
return new ApiError('NETWORK_ERROR', error instanceof Error ? error.message : 'Unknown error');
}
});
if (err) {
// Add request context to error
return [null, new Error(`API request failed: ${endpoint}`, { cause: err })] as const;
}
return [response, null] as const;
}
async getUser(id: string) {
let [user, err] = await this.request<User>(`/users/${id}`);
if (err) {
// Add operation context to error
return [null, new Error(`Failed to get user ${id}`, { cause: err })] as const;
}
return [user, null] as const;
}
}
// Usage
const api = new ApiClient('https://api.example.com', 'token');
let [user, err] = await api.getUser('123');
if (err) {
console.error('Error chain:', err.cause?.cause?.message);
}