Skip to content

Status Reference

The first argument to expectStatus declares which statuses count as success. Everything else is an error.

FormExampleMatches
Exact code200Only 200
Array of codes[200, 201]200 or 201
Range'2xx'200–299
Range'3xx'300–399
Range'4xx'400–499
Range'5xx'500–599
Range'1xx'100–199
Built-in group'success'200–299 (same as '2xx')
Built-in group'error'400–599 (same as '4xx' + '5xx')
Custom group'auth'Instance-defined (e.g. [401, 403])
Negation'!4xx'Anything except 400–499
Negation'!error'Anything except 400–599
Negation'!auth'Anything except group members
Mixed array[200, '3xx']200 or any 300–399
Mixed array['success', 404]Any 2xx or 404

Dispatch keys go in the options object. They determine how specific error statuses are handled.

KeyExampleMatches
Exact code404Only 404
Range'4xx'Any 400–499
Range'5xx'Any 500–599
Custom group'auth'Instance-defined group members

Not valid as dispatch keys: 'success', 'error', '1xx', '2xx', '3xx', negations ('!4xx').

Value typeBehaviourReturn type effect
stringMessage — throws ExpectStatusError with this textNo change
(body) => THandler — receives typed body, can return or throwWidens to SuccessBody | T
await expectStatus(201, response, {
404: "Not found.", // message
409: (body) => redirect(`/org/${body.id}`), // handler
"5xx": "Service unavailable.", // range message
auth: () => redirect("/sign-in"), // custom group handler
});

When multiple keys could match, specificity wins:

PriorityKey typeExample
1 (highest)Exact code404
2Range'4xx'
3 (lowest)Custom group'auth'

Handlers (functions) are always checked before messages (strings), even across per-call and instance defaults:

StepSourceType
1Per-call dispatchHandler (function) — most specific match
2Instance defaultsHandler (function) — most specific match
3Per-call dispatchMessage (string) — most specific match
4Instance defaultsMessage (string) — most specific match
5extractMessage(body)Pulls message from response body
6fallbackMessageLast-resort static string
7onErrorObservability hook — fires once before throwing
8recoverTrue catch-all — returns a value instead of throwing

Within each step, specificity applies: exact code → range → custom group.

When the status matches the expected status:

StepWhat happens
1onSuccess(response) fires (side-effect only)
2transform(body) reshapes the body (if provided)
3Return the body (or transformed body)
GroupRangeCodes
'success''2xx'200–299
'error''4xx' + '5xx'400–599

Defined on the instance with groups:

const expectStatus = createExpectStatus({
groups: {
auth: [401, 403],
retryable: [408, 429, 500, 502, 503, 504],
cacheable: [200, 203, 300, 301],
},
});

Custom groups work as:

  • Status specifiersexpectStatus('auth', response)
  • Dispatch keys{ auth: 'Please sign in.' }
  • NegationsexpectStatus('!auth', response)
RangeHTTP classCodes
'1xx'Informational100–199
'2xx'Success200–299
'3xx'Redirection300–399
'4xx'Client Error400–499
'5xx'Server Error500–599

Ranges work as both status specifiers and dispatch keys.

FormAs status specifierAs dispatch key
Exact code (200)
Range ('4xx')
'success' / 'error'
Custom group ('auth')
Negation ('!4xx')
Array ([200, 201])