SkillAgentSearch skills...

Resguard

šŸ›” Typescript promise result guarding library

Install / Use

/learn @meistrari/Resguard
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<div align=center>

šŸ›”ļø resguard

npm version npm downloads Codecov

</div>

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.

highlights

  • šŸ›” 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

usage

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
}

<sup><strong>Both the data and error properties of the result are correctly typed</strong></sup>

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)

<sup><strong>resguard can also be used with functions. When they are sync, the result also is!</strong></sup>

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)

<sup><strong>resguard can also be used with async functions.</strong></sup>

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)

<sup><strong>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.</strong></sup>

<table > <tr> <th><p><strong>āŒ depressing</strong></p></th> <th><p><strong>āœ… awesome</strong></p></th> </tr> <tr> <td>
let result

try {
    result = await client.getItems()
} catch (error) {
    handle(error)
}
</td> <td>
const result = await resguard(client.getItems())
if (result.error) 
    handle(result.error)
</td> </tr> <tr><td></td><td></td></tr> <tr> <td>
let result

try {
    result = await client.longRequest()
} catch (e: any) {
    const error: ClientError = e
    if (error.code === 'TIMEOUT')
      handleTimeout()
}
</td> <td>
const result = await resguard(client.longRequest(), ClientError)
if (result.error) {
    if (error.code === 'TIMEOUT')
      handleTimeout()
}
</td> </tr> <tr><td></td><td></td></tr> <tr> <td>
let result
try {
  result = JSON.parse(data)
} catch (e: any) {
  const error: SyntaxError = e
  handle(error)
}
</td> <td>
const result = resguard(() => JSON.parse(data), SyntaxError)
if (result.error) 
    handle(result.error)
</td> </tr> <tr><td></td><td></td></tr> <tr> <td>
let data: { test: number }

try {
  data = JSON.parse('{ test: 1 }')
} catch (e: any) {
  const error: SyntaxError = e
  handle(error)
}

console.log(data.test)
</td> <td>
const { data, error } = resguard<{ test: number}>(
    () => JSON.parse('{ test: 1 }'), 
    SyntaxError
)

if (error) 
    handle(error)

console.log(data.test)
</td> </tr> <tr><td></td><td></td></tr> <tr> <td>
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
}
</td> <td>
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
}
</td> </tr> </table>

using tuples

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;
}

custom error handling

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;
}

Related Skills

View on GitHub
GitHub Stars58
CategoryDevelopment
Updated1y ago
Forks0

Languages

TypeScript

Security Score

85/100

Audited on Nov 13, 2024

No findings