Skip to content

Message Extraction

When no handler or message matches a non-success status, expect-status tries to extract a useful message from the response body. You can customize or replace this logic.

The built-in extractor checks these shapes in priority order — the first match wins:

ExtractorBody shapeExample
stringBodyBody is a non-empty string"Not found"
messageFieldbody.message{ message: "Not found" }
problemDetailRFC 7807 body.detail or body.title{ detail: "Not found", status: 404 }
arrayErrorsbody.errors[0].message or body.errors[0]{ errors: [{ message: "…" }] }
springErrorbody.error{ error: "Not Found", status: 404 }

Replace the default with your own function:

const expectStatus = createExpectStatus({
extractMessage: (body) => {
if (typeof body === 'object' && body !== null) {
const b = body as Record<string, unknown>
return (
nonEmptyString(b.detail) ??
nonEmptyString(b.error) ??
nonEmptyString(b.message)
)
}
return undefined
},
})

Return undefined to fall through to the fallbackMessage.

Use chainExtractors to combine built-in primitives in your own order:

import {
chainExtractors,
problemDetail,
messageField,
springError,
stringBody,
} from 'expect-status'
const expectStatus = createExpectStatus({
extractMessage: chainExtractors(
problemDetail, // RFC 7807 first
messageField, // then body.message
springError, // then body.error
stringBody, // finally plain string body
),
})

Order matters — the leftmost extractor wins.

If the extractor returns undefined, the fallbackMessage is used:

const expectStatus = createExpectStatus({
extractMessage: (body) => (body as { detail?: string }).detail,
fallbackMessage: 'An error occurred. Please try again.',
})

The default fallback is 'Request failed with an unexpected status.'.