@shkumbinhsn/try-catch 0.0.1 → 0.0.2
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 +100 -48
- package/lib/try-catch.d.ts +1 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
|
+

|
|
2
|
+
[](https://www.npmjs.com/package/@shkumbinhsn/try-catch)
|
|
3
|
+
[](https://www.npmjs.com/package/@shkumbinhsn/try-catch)
|
|
1
4
|
# Type-Safe Try-Catch Pattern for TypeScript
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
A lightweight TypeScript utility that provides type-safe error handling through a functional approach. This library allows you to explicitly define error types while maintaining full TypeScript inference and zero runtime overhead.
|
|
4
7
|
|
|
5
|
-
##
|
|
8
|
+
## Installation
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
```bash
|
|
11
|
+
npm install @shkumbinhsn/try-catch
|
|
12
|
+
```
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
- For functions throwing multiple errors (e.g., `CustomError`, `Error`), use `Throws` to explicitly declare them.
|
|
14
|
+
## Key Features
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
- **🔒 Type Safety**: Explicitly declare what errors your functions can throw
|
|
17
|
+
- **🎯 Zero Runtime Overhead**: Types are compile-time only using TypeScript's structural typing
|
|
18
|
+
- **🔄 Async/Sync Support**: Works seamlessly with both synchronous and asynchronous functions
|
|
19
|
+
- **📦 Lightweight**: Minimal footprint with no dependencies
|
|
20
|
+
- **🧠 Smart Inference**: Falls back to standard TypeScript inference when no error types are specified
|
|
21
|
+
- **🛡️ Tuple-based**: Returns `[data, error]` tuples for explicit error handling
|
|
16
22
|
|
|
17
|
-
##
|
|
23
|
+
## Why Use This Pattern?
|
|
24
|
+
|
|
25
|
+
Traditional try-catch blocks in TypeScript don't provide type information about what errors might be thrown. This library solves that by:
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
1. Making error types explicit in function signatures
|
|
28
|
+
2. Forcing explicit error handling through tuple destructuring
|
|
29
|
+
3. Providing better IntelliSense and type checking
|
|
30
|
+
4. Maintaining compatibility with existing code
|
|
21
31
|
|
|
22
32
|
---
|
|
23
33
|
|
|
@@ -26,7 +36,7 @@ This repository demonstrates an experimental approach to handling try-catch bloc
|
|
|
26
36
|
### Defining a Function with Error Handling
|
|
27
37
|
|
|
28
38
|
```typescript
|
|
29
|
-
import { tryCatch, type Throws } from "
|
|
39
|
+
import { tryCatch, type Throws } from "@shkumbinhsn/try-catch";
|
|
30
40
|
|
|
31
41
|
class CustomError extends Error {}
|
|
32
42
|
|
|
@@ -35,66 +45,108 @@ function iMightFail(): string & Throws<CustomError> {
|
|
|
35
45
|
if (random > 0.2) {
|
|
36
46
|
return "success";
|
|
37
47
|
} else if (random > 0.5) {
|
|
38
|
-
throw new CustomError();
|
|
48
|
+
throw new CustomError("Something went wrong");
|
|
39
49
|
}
|
|
40
|
-
throw new Error();
|
|
50
|
+
throw new Error("Generic error");
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
const [data, error] = tryCatch(() => iMightFail());
|
|
44
54
|
|
|
45
|
-
if (
|
|
46
|
-
console.log("
|
|
47
|
-
//
|
|
55
|
+
if (error) {
|
|
56
|
+
console.log("Operation failed:", error.message);
|
|
57
|
+
// TypeScript knows: error is Error | CustomError
|
|
48
58
|
} else {
|
|
49
|
-
console.log("
|
|
50
|
-
//
|
|
59
|
+
console.log("Operation succeeded:", data);
|
|
60
|
+
// TypeScript knows: data is string
|
|
51
61
|
}
|
|
52
|
-
|
|
53
62
|
```
|
|
54
63
|
|
|
55
64
|
### Async Functions with Errors
|
|
56
65
|
|
|
57
66
|
```typescript
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
await
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return "success";
|
|
67
|
-
} else if (random > 0.5) {
|
|
68
|
-
throw new CustomError();
|
|
67
|
+
async function fetchUserData(id: string): Promise<User & Throws<ValidationError | NetworkError>> {
|
|
68
|
+
if (!id) {
|
|
69
|
+
throw new ValidationError("User ID is required");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const response = await fetch(`/api/users/${id}`);
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
throw new NetworkError("Failed to fetch user data");
|
|
69
75
|
}
|
|
70
|
-
|
|
76
|
+
|
|
77
|
+
return response.json();
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
const [
|
|
80
|
+
const [userData, error] = await tryCatch(() => fetchUserData("123"));
|
|
74
81
|
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
if (error) {
|
|
83
|
+
if (error instanceof ValidationError) {
|
|
84
|
+
console.log("Validation error:", error.message);
|
|
85
|
+
} else if (error instanceof NetworkError) {
|
|
86
|
+
console.log("Network error:", error.message);
|
|
87
|
+
} else {
|
|
88
|
+
console.log("Unexpected error:", error.message);
|
|
89
|
+
}
|
|
78
90
|
} else {
|
|
79
|
-
console.log("
|
|
80
|
-
|
|
91
|
+
console.log("User data:", userData);
|
|
92
|
+
// TypeScript knows: userData is User
|
|
81
93
|
}
|
|
82
94
|
```
|
|
83
95
|
|
|
84
|
-
###
|
|
96
|
+
### Without Explicit Error Types
|
|
97
|
+
|
|
98
|
+
When you don't specify error types, the library falls back to standard TypeScript inference:
|
|
85
99
|
|
|
86
100
|
```typescript
|
|
87
|
-
function
|
|
88
|
-
|
|
101
|
+
function regularFunction() {
|
|
102
|
+
return "success";
|
|
89
103
|
}
|
|
90
104
|
|
|
91
|
-
const [
|
|
105
|
+
const [data, error] = tryCatch(regularFunction);
|
|
92
106
|
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
107
|
+
if (error) {
|
|
108
|
+
console.log("Operation failed:", error.message);
|
|
109
|
+
// TypeScript knows: error is Error
|
|
96
110
|
} else {
|
|
97
|
-
|
|
98
|
-
|
|
111
|
+
console.log("Operation succeeded:", data);
|
|
112
|
+
// TypeScript knows: data is string
|
|
99
113
|
}
|
|
100
114
|
```
|
|
115
|
+
|
|
116
|
+
## API Reference
|
|
117
|
+
|
|
118
|
+
### `tryCatch<T>(fn: () => T): TryCatchReturn<T>`
|
|
119
|
+
|
|
120
|
+
Executes a function within a try-catch block and returns a result tuple.
|
|
121
|
+
|
|
122
|
+
**Parameters:**
|
|
123
|
+
- `fn`: Function to execute (can be sync or async)
|
|
124
|
+
|
|
125
|
+
**Returns:**
|
|
126
|
+
- `[data, null]` on success
|
|
127
|
+
- `[null, error]` on failure
|
|
128
|
+
|
|
129
|
+
### `Throws<T extends Error>`
|
|
130
|
+
|
|
131
|
+
Type utility for declaring error types in function signatures.
|
|
132
|
+
|
|
133
|
+
**Usage:**
|
|
134
|
+
```typescript
|
|
135
|
+
function myFunction(): ReturnType & Throws<MyError> {
|
|
136
|
+
// function implementation
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Limitations
|
|
141
|
+
|
|
142
|
+
- **Duplicate Definitions**: Error types must be declared in both the throw statement and return type
|
|
143
|
+
- **Runtime Validation**: No runtime enforcement of declared error types
|
|
144
|
+
- **Learning Curve**: Requires understanding of TypeScript's structural typing
|
|
145
|
+
|
|
146
|
+
## Contributing
|
|
147
|
+
|
|
148
|
+
Contributions are welcome! Please feel free to submit issues and pull requests.
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
MIT
|
package/lib/try-catch.d.ts
CHANGED
|
@@ -7,20 +7,7 @@ export type Throws<T extends Error> = {
|
|
|
7
7
|
|
|
8
8
|
type ExtractErrors<T> = T extends Throws<infer E> ? E : never;
|
|
9
9
|
|
|
10
|
-
type
|
|
11
|
-
|
|
12
|
-
type ExtractData<T> =
|
|
13
|
-
T extends string ? string :
|
|
14
|
-
T extends number ? number :
|
|
15
|
-
T extends boolean ? boolean :
|
|
16
|
-
T extends symbol ? symbol :
|
|
17
|
-
T extends bigint ? bigint :
|
|
18
|
-
T extends null ? null :
|
|
19
|
-
T extends undefined ? undefined :
|
|
20
|
-
T extends Function ? T :
|
|
21
|
-
Simplify<Omit<T, ErrorSymbol>>;
|
|
22
|
-
|
|
23
|
-
type DataError<T> = [ExtractData<T>, null] | [null, Error | ExtractErrors<T>];
|
|
10
|
+
type DataError<T> = [T, null] | [null, Error | ExtractErrors<T>];
|
|
24
11
|
type TryCatchReturn<T> = T extends Promise<infer R> ? Promise<DataError<R>> : DataError<T>;
|
|
25
12
|
|
|
26
13
|
export declare function tryCatch<T>(fn: () => T): TryCatchReturn<T>;
|