go-style-error
v1.0.0
Published
A utility library for elegant async/await error handling inspired by Go's error handling pattern
Maintainers
Readme
do
An elegant JavaScript/TypeScript asynchronous error handling library inspired by the Go language's error handling model.
✨ Features
- 🚀 Zero Dependencies - Lightweight, no external dependencies
- 🎯 Type-safe - full TypeScript support
- 🔄 Go style - returns
[error, data]tuples, avoiding the cumbersome syntax of try-catch - 🛡️ Elegant Degradation - support default values for more elegant error handling
- 📦 Multi-format - support for CommonJS and ES Modules
- 🧪 Fully tested - 100% test coverage
📦 Installation
npm install do
# or
yarn add do
# or
pnpm add do🚀 Quick start
basic usage
import { to } from 'do';
// traditional approach
try {
const user = await fetchUser(id);
console.log(user);
} catch (error) {
console.error('Failed to fetch user:', error.message);
}
// Using the do Library
const [error, user] = await to(() => fetchUser(id));
if (error) {
console.error('Failed to fetch user:', error.message);
return;
}
console.log(user);Error handling with default values
import { to } from 'do';
// If the API call fails, use the default
const [error, users] = await to(() => fetchUsers(), []);
// users will be [] if fetchUsers() fails
// Error Handling with Default Objects
const [error, settings] = await to(
() => fetchUserSettings(userId),
{ theme: 'light', notifications: false }
);📚 API reference
to<T>(asyncFn, defaultValue?)
Executes an asynchronous function and returns the [error, data] tuple.
** Parameters.
asyncFn: (... .args: any[]) => Promise<T>- the asynchronous function to executedefaultValue?: T- optional, default value when an error occurs
Returns:
Promise<[Error | null, T | undefined]>- tuple, the first element is the error (null on success), the second element is the data
toSync<T>(fn, defaultValue?) - the first element is the error (null on success), the second is the data
Synchronized version of the to function for handling synchronized functions that may throw errors.
Arguments:
fn: () => T- the synchronization function to be executeddefaultValue?: T- optional, default value when an error occurs
Returns:
[Error | null, T | undefined]- the tuple
toPromise<T>(promise, defaultValue?)
Wraps the Promise instance directly.
Parameters:
promise: Promise<T>- the Promise to be wrappeddefaultValue?: T- optionally, the default value when the Promise is rejected
Returns:
Promise<[Error | null, T | undefined]>- The tuple
💡 Usage Examples
1. API call handling
import { to } from 'do';
async function loadUserProfile(userId: number) {
const [userError, user] = await to(() => fetchUser(userId));
const [postsError, posts] = await to(() => fetchUserPosts(userId), []);
const [settingsError, settings] = await to(
() => fetchUserSettings(userId),
{ theme: 'light', notifications: false }
);
// We can continue to use the defaults even if something fails.
return {
user: user || { id: 0, name: 'Anonymous' },
posts: posts || [],
settings: settings || { theme: 'light', notifications: false }
};
}2. JSON parsing
import { toSync } from 'do';
function parseUserData(jsonString: string) {
const [error, userData] = toSync(() => JSON.parse(jsonString), {});
if (error) {
console.error('Invalid JSON:', error.message);
return null;
}
return userData;
}3. Database operations
import { to } from 'do';
async function createUser(userData: UserData) {
const [validationError, validatedData] = await to(() => validateUser(userData));
if (validationError) {
return { success: false, error: validationError.message };
}
const [dbError, user] = await to(() => db.users.create(validatedData));
if (dbError) {
return { success: false, error: 'Failed to create user' };
}
return { success: true, user };
}4. Documentation operations
import { toSync } from 'do';
import fs from 'fs';
function readConfigFile(path: string) {
const [readError, content] = toSync(() => fs.readFileSync(path, 'utf8'));
if (readError) {
console.error('Failed to read config file:', readError.message);
return null;
}
const [parseError, config] = toSync(() => JSON.parse(content), {});
if (parseError) {
console.error('Invalid config format:', parseError.message);
return null;
}
return config;
}5. network request
import { toPromise } from 'do';
async function fetchWithTimeout(url: string, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
const promise = fetch(url, { signal: controller.signal })
.then(res => res.json())
.finally(() => clearTimeout(timeoutId));
const [error, data] = await toPromise(promise, null);
if (error) {
console.error('Request failed:', error.message);
return null;
}
return data;
}🔧 Development
Install dependencies
pnpm install Run tests
pnpm test:watch Build the library
pnpm build Code formatting
pnpm format Type checking
pnpm typecheck 🤝 贡献
欢迎提交 Issue 和 Pull Request!
📄 许可证
MIT License
🙏 致谢
This library was inspired by:
- Go language's error handling model
- await-to-js Library
- Community discussions on graceful error handling
** Makes asynchronous error handling simple and elegant! ** 🎉
