hcengineering/platform · error · Error
response.statusText
Error message
response.statusText
What it means
The rest-client's generic `find` method GETs a communication API endpoint and, when `response.ok` is false, throws an Error whose message is the HTTP response.statusText. It surfaces any 4xx/5xx from the server with essentially no context (no URL, no status code number, no body), which makes it hard to diagnose. Callers are findNotificationContexts, findNotifications, findMessagesMeta, findMessagesGroups.
Solutions
- Log response.status (not just statusText) in the client or at the call site to identify the actual HTTP code.
- Verify the bearer token passed to the client is valid and not expired.
- Confirm the workspace name and operation path match the deployed communication service API.
- Check the server logs for the corresponding 5xx if status is 500.
- Consider capturing response body in the thrown error for diagnostics (patch rest.ts).
Example fix
// before
if (!response.ok) {
throw new Error(response.statusText)
}
// after
if (!response.ok) {
throw new Error(`GET ${requestUrl} failed: ${response.status} ${response.statusText}`)
} Defensive patterns
Strategy: try-catch
Validate before calling
function assertClientConfig(client) {
if (!client.token || typeof client.token !== 'string') throw new Error('rest-client: valid bearer token required before find calls')
if (!client.workspace) throw new Error('rest-client: workspace must be set')
} Type guard
function isHttpResponseOk(res: Response): res is Response & { ok: true } {
return res.ok
} Try / catch
try {
const msgs = await client.findMessagesMeta(params)
} catch (e) {
// e.message is bare statusText — inspect it and add context
console.error(`findMessagesMeta failed: ${e.message}; check token/workspace`)
if (e.message === 'Unauthorized') await refreshToken()
throw e
} Prevention
- Refresh bearer tokens before expiry; handle 401 by re-authenticating.
- Validate workspace name/operation paths against the deployed API version.
- Prefer capturing response.status, since statusText may be empty (HTTP/2).
- Monitor communication service health before bulk find operations.
When it happens
Trigger: Calling any find* method (findNotificationContexts/findNotifications/findMessagesMeta/findMessagesGroups) against /api/v1/request/communication/... when the server responds non-OK: 401/403 (bad/expired bearer token), 404 (wrong workspace or operation), 500 (server error).
Common situations: Expired or misconfigured auth token in this.token; wrong workspace name in the client config; server downtime or route renamed after API version change; retries exhausted (the throw happens inside retry, so the last failure is reported).
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Download failed
- err.message
- Export failed to start
- Failed to complete multipart upload
- Failed to complete multipart upload
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/e3b0a93d6874c033.
Report an issue: GitHub.
Appendix: source
Thrown at foundations/communication/packages/rest-client/src/rest.ts:108
modifiedBy,
modifiedOn: Date.now()
}
}
private async find<T>(operation: string, params: Record<string, any>): Promise<T[]> {
const searchParams = new URLSearchParams()
if (Object.keys(params).length > 0) {
searchParams.append('params', JSON.stringify(params))
}
const requestUrl = concatLink(
this.endpoint,
`/api/v1/request/communication/${operation}/${this.workspace}?${searchParams.toString()}`
)
return await retry(
async () => {
const response = await fetch(requestUrl, this.requestInit())
if (!response.ok) {
throw new Error(response.statusText)
}
return await extractJson<T[]>(response)
},
{ retries }
)
}
async event (event: Event, socialId: SocialID): Promise<EventResult> {
const response = await fetch(concatLink(this.endpoint, `/api/v1/tx/${this.workspace}`), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + this.token
},
keepalive: true,
body: JSON.stringify(this.wrapEvent(event, socialId))
})
if (!response.ok) {View on GitHub (pinned to 63e28dc964)