Examples
Interactive demo
Try every feature of @cometloop/safe right in your browser. Click buttons, tweak inputs, and watch live results from the actual library.
safe.wrap
Wraps a synchronous function so it returns a [data, error] tuple instead of throwing.
import { safe } from '@cometloop/safe'
const parseJson = (input: string) => {
return JSON.parse(input)
}
const safeParseJson = safe.wrap(parseJson)
const [data, error] = safeParseJson('{"name": "Alice", "age": 30}')
if (error) {
console.log('Parse failed:', error.message)
} else {
console.log('Parsed:', data)
}
Controls
Output
Click a button to run...
safe.wrapAsync
Wraps an async function so it returns a Promise<[data, error]> tuple instead of rejecting.
import { safe } from '@cometloop/safe'
// Toggle this to simulate success or failure
const shouldFail = false
const fetchUser = async () => {
return new Promise<{ id: number; name: string }>((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(new Error('Network timeout'))
} else {
resolve({ id: 1, name: 'Alice' })
}
}, 1000)
})
}
const safeFetchUser = safe.wrapAsync(fetchUser)
const [user, error] = await safeFetchUser()
if (error) {
console.log('Fetch failed:', error.message)
} else {
console.log('User:', user)
}
Controls
Output
Click a button to run...
safe.wrap with args
Wrapped functions forward arguments and preserve type safety on inputs and outputs.
import { safe } from '@cometloop/safe'
const divide = (a: number, b: number) => {
if (b === 0) throw new Error('Division by zero')
return a / b
}
const safeDivide = safe.wrap(divide)
const [result, error] = safeDivide(10, 2)
if (error) {
console.log('Error:', error.message)
} else {
console.log('Result:', result) // 5
}
Controls
Output
Click a button to run...
safe.wrapAsync with args
Wrapped async functions forward arguments and preserve type safety on inputs and outputs.
import { safe } from '@cometloop/safe'
// Toggle this to simulate a server error
const shouldFail = false
const fetchUser = async (id: string) => {
return new Promise<{ id: string; name: string; email: string }>(
(resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(new Error('HTTP 500'))
} else {
resolve({ id, name: 'Alice', email: 'alice@example.com' })
}
}, 800)
}
)
}
const safeFetchUser = safe.wrapAsync(fetchUser)
const [user, error] = await safeFetchUser('42')
if (error) {
console.log('Fetch failed:', error.message)
} else {
console.log('User:', user)
}
Controls
Output
Click a button to run...