typescript / intermediate
Snippet
Intercepting Async Results using Custom Result Wrapper Objects
Instead of relying on unhandled promise rejections or throwing raw exceptions across asynchronous boundaries, returning explicit Result union types forces calling code to handle both success and error branches safely.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type Result<T> = { success: true; value: T } | { success: false; error: Error };async function safeFetchData(url: string): Promise<Result<string>> {try {if (!url) throw new Error("URL cannot be empty");return { success: true, value: `Data from ${url}` };} catch (err) {return {success: false,error: err instanceof Error ? err : new Error(String(err))};}}async function run() {const res = await safeFetchData("");if (!res.success) {console.error("Failed:", res.error.message);}}
Breakdown
1
type Result<T> = { success: true; value: T } | { success: false; error: Error };
Creates a union type explicitly modeling outcome states with boolean discriminator properties.
2
return { success: false, error: err instanceof Error ? err : new Error(String(err)) };
Ensures any caught unknown error value is safely converted into a standardized Error instance.
3
if (!res.success) { console.error("Failed:", res.error.message); }
Leverages TypeScript control flow narrowing to access the error property safely.