Skip to content

Create Instance

createExpectStatus returns a configured expectStatus function. Set up defaults, error logging, and message extraction once — every call site inherits them.

import { createExpectStatus } from 'expect-status'
export const expectStatus = createExpectStatus({
fallbackMessage: 'Something went wrong.',
defaults: {
401: 'Please sign in.',
403: 'You do not have permission.',
'5xx': 'Service is temporarily unavailable.',
},
onError: (err, res) => {
Sentry.captureException(err, { extra: { status: res.status } })
},
onSuccess: (res) => {
analytics.track('api_success', { status: res.status })
},
})

Now use expectStatus everywhere — per-call dispatch shadows these defaults when needed:

const org = await expectStatus(201, api.createOrg({ body: data }), {
409: ({ orgId }) => redirect(`/org/${orgId}`),
})

Instance defaults use the same flat dispatch as per-call — strings are messages, functions are handlers:

const expectStatus = createExpectStatus({
defaults: {
401: 'Please sign in.',
403: 'You do not have permission.',
429: (body) => {
throw new Error('Too many requests. Please slow down.')
},
'5xx': 'Service is temporarily unavailable.',
},
})

Per-call entries always shadow defaults at the same key.

Define named status groups, then use them as expected status arguments or dispatch keys:

const expectStatus = createExpectStatus({
groups: {
auth: [401, 403],
retryable: [408, 429, 500, 502, 503, 504],
},
})
// As expected status
await expectStatus('!auth', response)
// As dispatch keys
await expectStatus(200, response, {
auth: () => redirect('/sign-in'),
retryable: 'Please try again shortly.',
})

Replace the default ExpectStatusError with your own:

class RequestError extends Error {
constructor(message: string, public status: number, public body: unknown) {
super(message)
this.name = 'RequestError'
}
}
const expectStatus = createExpectStatus({
errorFactory: (message, response) =>
new RequestError(message, response.status, response.body),
})

Create separate instances for different contexts:

export const publicApi = createExpectStatus({
defaults: { 401: 'Please sign in to access the public API.' },
})
export const adminApi = createExpectStatus({
defaults: {
401: 'Admin access required.',
403: 'You do not have admin privileges.',
},
})
OptionTypeDescription
defaultsflat dispatch objectInstance-wide handlers and messages
groupsRecord<string, number[]>Named status groups
errorFactory(msg, response) => ErrorCustom error constructor
extractMessage(body) => string | undefinedCustom message extraction
fallbackMessagestringLast-resort error message
onError(err, response) => voidError observability hook
onSuccess(response) => voidSuccess observability hook
statusFieldstringCustom status field name (default: 'status')
bodyFieldstringCustom body field name (default: 'body')