Guides
Handle errors
Which methods throw, which don't, and how to handle them
Most errors are handled internally by the SDK. Only protect() surfaces errors to your code, and only errors from your function or from timeouts.
Which methods throw
| Method | Throws? | Details |
|---|---|---|
constructor | Yes | ConfigurationError if required options are missing. |
init() | Never | Logs warnings, retries in background. |
ready() | Never | Resolves when init completes. |
protect() | Yes | TimeoutError if timeout exceeded. Rethrows errors from your function. |
isOpen() | Never | Returns false on any error. |
isClosed() | Never | Returns true on any error. |
status() | Never | Returns null on any error. |
breakers() | Never | Returns [] on any error. |
reset() | Never | Logs warnings on flush failure. |
close() | Never | Logs warnings on flush failure. |
flushMetrics() | Never | Logs warnings on failure. |
stopMetrics() | Never | Logs warnings on failure. |
TimeoutError
Thrown when your function exceeds the timeout option:
import { TimeoutError } from '@openfuseio/sdk'
try {
await openfuse.breaker('stripe-get-customer').protect(
(signal) => stripe.customers.retrieve(customerId, { signal }),
{ timeout: 3000 },
)
} catch (error) {
if (error instanceof TimeoutError) {
// Function took longer than 3000ms
}
}Your function's errors
Any error thrown by the function you pass to protect() is rethrown as-is:
try {
await openfuse.breaker('external-api').protect(() => {
throw new Error('Service is having a bad day')
})
} catch (error) {
// error is the exact Error your function threw
}AbortOperationError
Thrown when a signal option is provided and the signal aborts:
import { AbortOperationError } from '@openfuseio/sdk'
const controller = new AbortController()
controller.abort()
try {
await openfuse.breaker('stripe-get-customer').protect(
(signal) => stripe.customers.retrieve(customerId, { signal }),
{ signal: controller.signal },
)
} catch (error) {
if (error instanceof AbortOperationError) {
// Operation was cancelled
}
}Classify errors with isServerOrNetworkError
The SDK exports a utility to distinguish transient errors from permanent ones:
import { isServerOrNetworkError } from '@openfuseio/sdk'
try {
await openfuse.breaker('external-api').protect(
() => externalService.getData(),
)
} catch (error) {
if (isServerOrNetworkError(error)) {
// 5xx, network error, or timeout: safe to retry
} else {
// 4xx or application error: don't retry
}
}Recommended pattern
import { TimeoutError, isServerOrNetworkError } from '@openfuseio/sdk'
async function fetchRecommendations(userId: string) {
try {
return await openfuse.breaker('recommendations').protect(
(signal) => recommendationService.get(userId, { signal }),
{
timeout: 2000,
fallback: () => [],
},
)
} catch (error) {
if (error instanceof TimeoutError) {
return []
}
if (isServerOrNetworkError(error)) {
return []
}
throw error
}
}