npm package: @solaeter/await-to-try
Description: A Rust-inspired async error handling library with dual-mode distribution
Author: Solaeter
Latest version: 0.1.0

# @solaeter/await-to-try

> A Rust-inspired async error handling library with dual-mode distribution

Eliminate try-catch hell and handle async errors elegantly in JavaScript/TypeScript.

## Features

- **Try-Catch Hell Elimination** - Simplify async error handling with a clean API
- **Dual-Mode Distribution** - Use as an NPM library or inject source code via CLI
- **Chainable Enhancements** - `.toast()` for error notifications and `.resume()` for fallback values
- **Highly Customizable** - Inject and modify source code to fit your needs

## Installation

### Library Mode (NPM)

```bash
npm install @solaeter/await-to-try
```

### Source Mode (CLI)

```bash
npx solaeter-to
```

The CLI will guide you through:
1. Selecting a template
2. Choosing the destination directory (default: `./src/utils`)
3. Injecting the source code with custom toast logic

## Quick Start

### Library Mode

```typescript
import { _to } from '@solaeter/await-to-try';

// Handle a Promise
const { ok, result, error } = await _to(fetch('/api/data'));

if (ok) {
  console.log('Data:', result);
} else {
  console.error('Failed:', error);
}
```

### Source Mode

After running the CLI:

```typescript
import { _to } from './utils/to';

// Same API as library mode
const { ok, result, error } = await _to(asyncOperation());
```

## API

### `_to(task)`

Wraps a Promise or function execution result in a standardized format.

**Parameters:**

- `task`: `Promise<T> | (() => Promise<T>) | (() => T>` - The task to handle

**Returns:** `Promise<PromiseProxy<T>>` - A promise that resolves to a result object

**Result Structure:**

```typescript
{
  ok: boolean;      // true if successful, false if failed
  result?: T;       // the result value (when ok is true)
  error?: unknown;  // the error object (when ok is false)
}
```

## Usage Examples

### Basic Usage

```typescript
// Handle a Promise
const { ok, result, error } = await _to(Promise.resolve(42));
console.log(ok);    // true
console.log(result); // 42

// Handle an async function
const { ok, result, error } = await _to(async () => {
  const res = await db.query('SELECT * FROM users');
  return res;
});

// Handle a sync function
const { ok, result, error } = await _to(() => {
  return JSON.parse(jsonString);
});
```

### Using `.toast()` for Error Notifications

When an operation fails, `.toast()` displays an error message:

```typescript
await _to(asyncOperation)
  .toast('操作失败，请重试');

// Only shows toast when the operation fails
```

**Customizing Toast Logic:**

In Source Mode, edit the toast logic in the injected file:

```typescript
// Example: Using Ant Design
import { message } from 'antd';

// In the toast method:
message.error(message);

// Example: Using Element UI
import { ElMessage } from 'element-plus';

// In the toast method:
ElMessage.error(message);

// Example: Using React Toastify
import { toast } from 'react-toastify';

// In the toast method:
toast.error(message);
```

### Using `.resume()` for Fallback Values

When an operation fails, `.resume()` returns a fallback value:

```typescript
// Simple fallback
const data = await _to(fetchUserData())
  .resume({ id: 0, name: 'Guest' });

// If fetchUserData fails, returns the guest user object
```

### Combining `.toast()` and `.resume()`

```typescript
const items = await _to(fetchItems())
  .toast('列表加载失败，请检查网络')
  .resume([]);

// If fetchItems() fails:
// 1. Shows toast message
// 2. Returns empty array []
```

## Advanced Examples

### User Data Fetching

```typescript
async function getUserProfile(userId: number) {
  const { ok, result: user, error } = await _to(
    fetch(`/api/users/${userId}`).then(res => res.json())
  );

  if (!ok) {
    return null;
  }

  return user;
}

// Or with chaining
const user = await getUserProfile(1)
  .toast('用户数据加载失败')
  .resume(null);
```

### Multiple Async Operations

```typescript
async function loadDashboard() {
  const [users, posts, comments] = await Promise.all([
    _to(fetchUsers()),
    _to(fetchPosts()),
    _to(fetchComments())
  ]);

  const usersData = users[0].ok ? users[0].result : [];
  const postsData = posts[0].ok ? posts[0].result : [];
  const commentsData = comments[0].ok ? comments[0].result : [];

  return { users: usersData, posts: postsData, comments: commentsData };
}
```

### Error Recovery

```typescript
async function fetchDataWithRetry(url: string, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const { ok, result, error } = await _to(fetch(url));

    if (ok) {
      return result;
    }

    if (i === maxRetries - 1) {
      await _to(Promise.reject(error))
        .toast(`请求失败，已重试 ${maxRetries} 次`);
    }
  }

  return null;
}
```

## CLI Usage

### Interactive Mode

```bash
npx solaeter-to
```

You'll be prompted to:
1. Choose a template (currently: `to.ts`)
2. Specify the output directory (default: `./src/utils`)
3. Confirm the injection

The injected file will have:
- Your project name
- Current date
- Customizable toast logic
- Full source code access

### Customizing Injected Code

After injection, edit `src/utils/to.ts` to customize:

```typescript
// Find the toast method in the file
if (prop === 'toast') {
  return (message: string) => {
    if (!target.ok && target.error) {
      // ========================================
      // Toast 逻辑 - 自定义区域
      // ========================================
      // Add your custom toast implementation here
      showToast({ type: 'error', message });
      // ========================================
    }
    return target;
  };
}
```

## Comparison

### Traditional Try-Catch

```typescript
try {
  const response = await fetch('/api/data');
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
  // Fallback handling
}
```

### Using _to

```typescript
const { ok, result: data } = await _to(
  fetch('/api/data').then(res => res.json())
)
  .toast('数据加载失败')
  .resume(null);

if (data) {
  console.log(data);
}
```

## License

MIT

## Author

Solaeter

## Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.