@shkumbinhsn/try-catch 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# @shkumbinhsn/try-catch
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@shkumbinhsn/try-catch)
|
|
4
|
+
[](https://www.npmjs.com/package/@shkumbinhsn/try-catch)
|
|
5
|
+
|
|
6
|
+
Type-safe error handling for TypeScript using a functional `[data, error]` tuple pattern.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @shkumbinhsn/try-catch
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Type Safety**: Explicitly declare what errors your functions can throw
|
|
17
|
+
- **Zero Runtime Overhead**: Types are compile-time only
|
|
18
|
+
- **Async/Sync Support**: Works with both synchronous and asynchronous functions
|
|
19
|
+
- **Lightweight**: No dependencies, minimal footprint
|
|
20
|
+
- **Tuple-based**: Returns `[data, error]` for explicit error handling
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Basic Example
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { tryCatch, type Throws } from "@shkumbinhsn/try-catch";
|
|
28
|
+
|
|
29
|
+
class CustomError extends Error {
|
|
30
|
+
name = "CustomError" as const;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function riskyOperation(): string & Throws<CustomError> {
|
|
34
|
+
if (Math.random() > 0.5) {
|
|
35
|
+
throw new CustomError("Something went wrong");
|
|
36
|
+
}
|
|
37
|
+
return "success";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const [data, error] = tryCatch(() => riskyOperation());
|
|
41
|
+
|
|
42
|
+
if (error) {
|
|
43
|
+
// TypeScript knows: error is Error | CustomError
|
|
44
|
+
console.error("Failed:", error.message);
|
|
45
|
+
} else {
|
|
46
|
+
// TypeScript knows: data is string
|
|
47
|
+
console.log("Success:", data);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Async Functions
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { tryCatch, type Throws } from "@shkumbinhsn/try-catch";
|
|
55
|
+
|
|
56
|
+
class ValidationError extends Error {}
|
|
57
|
+
class NetworkError extends Error {}
|
|
58
|
+
|
|
59
|
+
async function fetchUser(id: string): Promise<User> & Throws<ValidationError | NetworkError> {
|
|
60
|
+
if (!id) {
|
|
61
|
+
throw new ValidationError("User ID is required");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const response = await fetch(`/api/users/${id}`);
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new NetworkError("Failed to fetch user");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return response.json();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Async usage
|
|
73
|
+
const [user, error] = await tryCatch(() => fetchUser("123"));
|
|
74
|
+
|
|
75
|
+
if (error) {
|
|
76
|
+
if (error instanceof ValidationError) {
|
|
77
|
+
console.error("Validation failed:", error.message);
|
|
78
|
+
} else if (error instanceof NetworkError) {
|
|
79
|
+
console.error("Network failed:", error.message);
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
console.log("User:", user.name);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Using `tc()` for Inferred Return Types
|
|
87
|
+
|
|
88
|
+
When you want TypeScript to infer your return type but still declare possible errors, use the `tc()` helper:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { tryCatch, tc } from "@shkumbinhsn/try-catch";
|
|
92
|
+
|
|
93
|
+
class APIError extends Error {}
|
|
94
|
+
class NetworkError extends Error {}
|
|
95
|
+
|
|
96
|
+
function fetchUser() {
|
|
97
|
+
const user = { id: "1", name: "Ada", email: "ada@example.com" };
|
|
98
|
+
// Return type is inferred as { id: string; name: string; email: string } & Throws<APIError | NetworkError>
|
|
99
|
+
return tc(user).mightThrow<APIError | NetworkError>();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const [data, error] = tryCatch(fetchUser);
|
|
103
|
+
|
|
104
|
+
if (error) {
|
|
105
|
+
// TypeScript knows: error is Error | APIError | NetworkError
|
|
106
|
+
console.error("Failed:", error.message);
|
|
107
|
+
} else {
|
|
108
|
+
// TypeScript knows: data is { id: string; name: string; email: string }
|
|
109
|
+
console.log("User email:", data.email);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Without Explicit Error Types
|
|
114
|
+
|
|
115
|
+
When you don't specify error types, the library falls back to standard TypeScript inference:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
function regularFunction() {
|
|
119
|
+
return "success";
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const [data, error] = tryCatch(regularFunction);
|
|
123
|
+
|
|
124
|
+
if (error) {
|
|
125
|
+
// TypeScript knows: error is Error
|
|
126
|
+
console.error("Failed:", error.message);
|
|
127
|
+
} else {
|
|
128
|
+
// TypeScript knows: data is string
|
|
129
|
+
console.log("Success:", data);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## API Reference
|
|
134
|
+
|
|
135
|
+
### `tryCatch<T>(fn: () => T): TryCatchReturn<T>`
|
|
136
|
+
|
|
137
|
+
Executes a function within a try-catch block and returns a result tuple.
|
|
138
|
+
|
|
139
|
+
**Parameters:**
|
|
140
|
+
- `fn`: Function to execute (can be sync or async)
|
|
141
|
+
|
|
142
|
+
**Returns:**
|
|
143
|
+
- `[data, null]` on success
|
|
144
|
+
- `[null, error]` on failure
|
|
145
|
+
|
|
146
|
+
### `Throws<T extends Error>`
|
|
147
|
+
|
|
148
|
+
Type utility for declaring error types in function signatures.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
function myFunction(): ReturnType & Throws<MyError> {
|
|
152
|
+
// implementation
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### `tc<T>(value: T): TcBuilder<T>`
|
|
157
|
+
|
|
158
|
+
Creates a builder for branding return values with error types.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
function myFunction() {
|
|
162
|
+
const result = computeSomething();
|
|
163
|
+
return tc(result).mightThrow<ErrorA | ErrorB>();
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Limitations
|
|
168
|
+
|
|
169
|
+
- **Duplicate Definitions**: Error types must be declared in both the throw statement and return type
|
|
170
|
+
- **Runtime Validation**: No runtime enforcement of declared error types
|
|
171
|
+
- **Learning Curve**: Requires understanding of TypeScript's structural typing
|
|
172
|
+
|
|
173
|
+
## ESLint Plugin
|
|
174
|
+
|
|
175
|
+
For automated enforcement of best practices, use the companion ESLint plugin:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
npm install -D @shkumbinhsn/try-catch-eslint
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
See [@shkumbinhsn/try-catch-eslint](https://www.npmjs.com/package/@shkumbinhsn/try-catch-eslint) for details.
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|
package/package.json
CHANGED