resguard
is a tiny utility that wraps promises and returns an object or tuple with data
and error
properties. It's useful for handling errors in async functions without having to use try/catch
blocks.
- π‘ Wraps promises and returns an object or tuple with data and error properties
- π― TypeScript support with type checking
- π οΈ Custom error handling support
- β‘ Minimal dependencies and small bundle size
npm install resguard
import { resguard } from 'resguard'
async function fetchData() {
const client = new APIClient()
const { data, error } = await resguard(client.getItems())
if (error)
handle(error)
const updated = await resguard(client.updateItems(data))
if (updated.error)
handle(updated.error)
return updated.data
}
Both the data
and error
properties of the result are correctly typed
import { resguard } from 'resguard'
const result = resguard(() => {
if (Math.random() > 0.5)
return true
else
throw new Error('Something went wrong')
})
if (result.error)
handle(result.error)
resguard
can also be used with functions. When they are sync, the result also is!
import { resguard } from 'resguard'
const result = await resguard(async () => {
const client = new APIClient()
const items = await client.getItems()
return items.map(item => item.id)
})
if (result.error)
handle(result.error)
resguard
can also be used with async functions.
import { resguardFn } from 'resguard'
const safeJSONParse = resguardFn(JSON.parse)
let result = safeJSONParse('{ "test": 1 }')
console.log(result.data) // { test: 1 }
result = safeJSONParse('{ missing the other one')
console.log(result.error) // SyntaxError: Unexpected character 'm' (1:2)
resguardFn
is a wrapper around resguard
that takes a function as an argument and returns a function that can be called with the same arguments, but guarded.
β depressing |
β awesome |
---|---|
let result
try {
result = await client.getItems()
} catch (error) {
handle(error)
} |
const result = await resguard(client.getItems())
if (result.error)
handle(result.error) |
let result
try {
result = await client.longRequest()
} catch (e: any) {
const error: ClientError = e
if (error.code === 'TIMEOUT')
handleTimeout()
} |
const result = await resguard(client.longRequest(), ClientError)
if (result.error) {
if (error.code === 'TIMEOUT')
handleTimeout()
} |
let result
try {
result = JSON.parse(data)
} catch (e: any) {
const error: SyntaxError = e
handle(error)
} |
const result = resguard(() => JSON.parse(data), SyntaxError)
if (result.error)
handle(result.error) |
let data: { test: number }
try {
data = JSON.parse('{ test: 1 }')
} catch (e: any) {
const error: SyntaxError = e
handle(error)
}
console.log(data.test) |
const { data, error } = resguard<{ test: number}>(
() => JSON.parse('{ test: 1 }'),
SyntaxError
)
if (error)
handle(error)
console.log(data.test) |
async function complexFunction() {
let items
try {
items = await client.getItems()
} catch (e: any) {
const error: ClientError = e
handle(error)
}
let updated
try {
updated = await client.updateItems(items)
} catch (e: any) {
const error: ClientError = e
handle(error)
}
return updated
} |
async function complexFunction() {
const items = await resguard(client.getItems(), ClientError)
if (items.error)
handle(items.error)
const updatedItems = await resguard(client.updateItems(items), ClientError)
if (updatedItems.error)
handle(updatedItems.error)
return updatedItems.data
} |
resguard can also return a tuple with data and error values:
import { resguard } from 'resguard';
async function fetchData() {
const service = new DataService();
const [[data, error]] = await resguard(service.getItems());
if (error) {
console.error("Error:", error);
return;
}
return data;
}
resguard supports custom error handling by allowing you to override the error type:
import { resguard } from 'resguard';
class CustomError extends Error {}
async function fetchData() {
const service = new DataService();
const [[data, error]] = await resguard(() => throw new CustomError('damn!'), CustomError);
if (error) {
console.error("Custom Error:", error);
console.log(error instanceof CustomError) // true
return;
}
return data;
}