Documentation Index
Fetch the complete documentation index at: https://docs.flowsbuilt.com/llms.txt
Use this file to discover all available pages before exploring further.
ChurnKitError
All SDK methods throw ChurnKitError on failure. It extends Error and adds status (HTTP status code) and code (typed error constant).
import { ChurnKitError, ErrorCode } from '@vgpprasad91/churnkit-sdk'
try {
await churn.score('user_123')
} catch (err) {
if (err instanceof ChurnKitError) {
console.log(err.message) // human-readable description
console.log(err.status) // HTTP status code (or undefined for network errors)
console.log(err.code) // 'TIMEOUT' | 'UNAUTHORIZED' | etc.
}
}
Error codes
| Code | HTTP | When |
|---|
ABORTED | — | The caller’s AbortSignal fired |
TIMEOUT | — | Request exceeded configured timeout |
NETWORK_ERROR | — | DNS failure, connection refused, etc. |
VALIDATION_ERROR | 400 | Invalid input (empty userId, bad threshold, etc.) |
UNAUTHORIZED | 401 | API key is missing, invalid, or revoked |
FORBIDDEN | 403 | API key lacks permission for this operation |
NOT_FOUND | 404 | Resource doesn’t exist (user not tracked, no watch, etc.) |
RATE_LIMITED | 429 | Too many requests — back off and retry |
SERVER_ERROR | 5xx | ChurnKit server error |
PAYLOAD_TOO_LARGE | 413 | bulkEvent() exceeded 500 items |
Handling patterns
Ignore cancellations
try {
const risk = await churn.score(userId, { signal })
return risk
} catch (err) {
if (err instanceof ChurnKitError && err.code === ErrorCode.ABORTED) {
return null // user navigated away — ignore
}
throw err
}
Exhaustive switch with type narrowing
import { ChurnKitError, ErrorCode, isKnownErrorCode } from '@vgpprasad91/churnkit-sdk'
try {
await churn.identify(userId, traits)
} catch (err) {
if (err instanceof ChurnKitError && isKnownErrorCode(err.code)) {
switch (err.code) {
case ErrorCode.UNAUTHORIZED:
logger.error('ChurnKit API key invalid — check CHURNKIT_API_KEY')
break
case ErrorCode.RATE_LIMITED:
logger.warn('ChurnKit rate limited — consider batching')
break
case ErrorCode.TIMEOUT:
logger.warn('ChurnKit timeout — request took too long')
break
case ErrorCode.VALIDATION_ERROR:
logger.error('ChurnKit validation error', err.message)
break
default:
logger.error('ChurnKit error', err.code, err.message)
}
}
}
Non-blocking with error logging
async function trackSafe(userId: string, event: string) {
try {
await churn.event(userId, event)
} catch (err) {
// Never let tracking failures break the main flow
if (err instanceof ChurnKitError) {
logger.warn('ChurnKit track failed', { code: err.code, event })
}
}
}
isKnownErrorCode()
Type guard that narrows err.code to a well-known ErrorCode constant — useful for exhaustive switch statements.
import { isKnownErrorCode } from '@vgpprasad91/churnkit-sdk'
if (err instanceof ChurnKitError && isKnownErrorCode(err.code)) {
// err.code is now typed as ErrorCode — IDE autocomplete works
switch (err.code) { ... }
}