guard
保护异步函数,捕获错误并返回统一的结果格式。
基础用法
typescript
import { guard } from 'radash'
const result = await guard(async () => {
const response = await fetch('https://api.example.com/data')
return response.json()
})
if (result.error) {
console.log('Error:', result.error)
} else {
console.log('Data:', result.data)
}
语法
typescript
function guard<T>(
fn: () => Promise<T>
): Promise<{ data: T | null; error: Error | null }>
参数
fn
(function): 要保护的异步函数
返回值
返回一个Promise,解析为包含data和error的对象。
示例
基本错误处理
typescript
import { guard } from 'radash'
async function fetchUserData(userId: number) {
const result = await guard(async () => {
const response = await fetch(`/api/users/${userId}`)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
return response.json()
})
if (result.error) {
console.error('Failed to fetch user:', result.error.message)
return null
}
return result.data
}
const user = await fetchUserData(123)
处理网络请求
typescript
import { guard } from 'radash'
async function makeApiCall(url: string) {
const result = await guard(async () => {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`)
}
return response.json()
})
return result
}
const apiResult = await makeApiCall('https://api.example.com/data')
if (apiResult.error) {
console.log('API Error:', apiResult.error.message)
} else {
console.log('API Data:', apiResult.data)
}
处理数据库操作
typescript
import { guard } from 'radash'
async function createUser(userData: any) {
const result = await guard(async () => {
// 模拟数据库操作
if (userData.email.includes('test')) {
throw new Error('Test emails are not allowed')
}
return {
id: Date.now(),
...userData,
createdAt: new Date()
}
})
if (result.error) {
console.error('User creation failed:', result.error.message)
return null
}
return result.data
}
const newUser = await createUser({
name: 'John Doe',
email: 'john@example.com'
})
处理文件操作
typescript
import { guard } from 'radash'
async function readFileContent(filePath: string) {
const result = await guard(async () => {
const fs = await import('fs/promises')
const content = await fs.readFile(filePath, 'utf-8')
return JSON.parse(content)
})
if (result.error) {
console.error('File read error:', result.error.message)
return null
}
return result.data
}
const config = await readFileContent('./config.json')
if (config) {
console.log('Config loaded:', config)
}
处理多个异步操作
typescript
import { guard } from 'radash'
async function processMultipleTasks() {
const tasks = [
guard(async () => {
await new Promise(resolve => setTimeout(resolve, 100))
return 'Task 1 completed'
}),
guard(async () => {
await new Promise(resolve => setTimeout(resolve, 200))
throw new Error('Task 2 failed')
}),
guard(async () => {
await new Promise(resolve => setTimeout(resolve, 150))
return 'Task 3 completed'
})
]
const results = await Promise.all(tasks)
results.forEach((result, index) => {
if (result.error) {
console.log(`Task ${index + 1} failed:`, result.error.message)
} else {
console.log(`Task ${index + 1} succeeded:`, result.data)
}
})
}
await processMultipleTasks()
处理超时操作
typescript
import { guard } from 'radash'
async function fetchWithTimeout(url: string, timeout: number) {
const result = await guard(async () => {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), timeout)
try {
const response = await fetch(url, {
signal: controller.signal
})
clearTimeout(timeoutId)
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
return response.json()
} catch (error) {
clearTimeout(timeoutId)
throw error
}
})
return result
}
const data = await fetchWithTimeout('https://api.example.com/data', 5000)
if (data.error) {
console.log('Request failed:', data.error.message)
} else {
console.log('Data received:', data.data)
}
处理重试逻辑
typescript
import { guard } from 'radash'
async function fetchWithRetry(url: string, maxRetries: number = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const result = await guard(async () => {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
return response.json()
})
if (!result.error) {
return result.data
}
console.log(`Attempt ${attempt} failed:`, result.error.message)
if (attempt < maxRetries) {
await new Promise(resolve => setTimeout(resolve, 1000 * attempt))
}
}
throw new Error(`Failed after ${maxRetries} attempts`)
}
try {
const data = await fetchWithRetry('https://api.example.com/data')
console.log('Success:', data)
} catch (error) {
console.error('All attempts failed:', error.message)
}
处理并发操作
typescript
import { guard } from 'radash'
async function processConcurrentRequests(urls: string[]) {
const requests = urls.map(url =>
guard(async () => {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
return response.json()
})
)
const results = await Promise.all(requests)
const successful = results.filter(r => !r.error)
const failed = results.filter(r => r.error)
console.log(`Successful: ${successful.length}, Failed: ${failed.length}`)
return {
successful: successful.map(r => r.data),
failed: failed.map(r => r.error)
}
}
const urls = [
'https://api.example.com/users',
'https://api.example.com/posts',
'https://api.example.com/comments'
]
const { successful, failed } = await processConcurrentRequests(urls)
处理条件操作
typescript
import { guard } from 'radash'
async function conditionalOperation(shouldFail: boolean) {
const result = await guard(async () => {
if (shouldFail) {
throw new Error('Operation failed as requested')
}
// 模拟成功操作
await new Promise(resolve => setTimeout(resolve, 100))
return { success: true, timestamp: Date.now() }
})
return result
}
// 成功的情况
const successResult = await conditionalOperation(false)
if (successResult.data) {
console.log('Operation succeeded:', successResult.data)
}
// 失败的情况
const failureResult = await conditionalOperation(true)
if (failureResult.error) {
console.log('Operation failed:', failureResult.error.message)
}
处理复杂错误处理
typescript
import { guard } from 'radash'
class CustomError extends Error {
constructor(message: string, public code: string) {
super(message)
this.name = 'CustomError'
}
}
async function complexOperation() {
const result = await guard(async () => {
// 模拟复杂的业务逻辑
const random = Math.random()
if (random < 0.3) {
throw new CustomError('Network error', 'NETWORK_ERROR')
} else if (random < 0.6) {
throw new CustomError('Validation error', 'VALIDATION_ERROR')
} else if (random < 0.8) {
throw new CustomError('Server error', 'SERVER_ERROR')
}
return { message: 'Operation completed successfully' }
})
if (result.error) {
if (result.error instanceof CustomError) {
switch (result.error.code) {
case 'NETWORK_ERROR':
console.log('Network issue, retrying...')
break
case 'VALIDATION_ERROR':
console.log('Invalid input data')
break
case 'SERVER_ERROR':
console.log('Server is down')
break
}
} else {
console.log('Unknown error:', result.error.message)
}
return null
}
return result.data
}
const result = await complexOperation()
注意事项
- 错误捕获: 捕获所有类型的错误,包括同步和异步错误
- 统一格式: 返回统一的结果格式,便于处理
- 类型安全: 提供完整的TypeScript类型支持
- 性能: 对性能影响很小,只是简单的错误包装
- 链式调用: 可以与其他异步函数链式调用
与其他方法的区别
try/catch
: 需要手动处理错误,guard
提供统一格式Promise.catch()
: 只处理Promise错误,guard
处理所有错误guard()
: radash提供的简洁的错误处理工具
实际应用场景
- API调用: 处理网络请求错误
- 数据库操作: 处理数据库连接和查询错误
- 文件操作: 处理文件读写错误
- 第三方服务: 处理外部服务调用错误
- 业务逻辑: 保护复杂的业务操作