hcengineering/platform · error
err.message
Error message
err.message
What it means
The export service's global Express error middleware. Errors that are instances of ApiError are returned with their own status code and { code, message }; any other thrown error is reported to Analytics, logged via measureCtx.warn, and returned as 500 with { message: err.message } — or the raw error object if the message is empty. It converts uncaught handler exceptions into JSON error responses.
Source
Thrown at services/export/pod-export/src/server.ts:648
await sourceClient.close()
await targetClient.close()
}
} catch (err: any) {
measureCtx.error('Export to workspace request failed:', err)
const errorMessage = err instanceof ApiError ? err.message : 'Export to workspace request failed'
res.status(err instanceof ApiError ? err.code : 500).send({ message: errorMessage })
}
})
)
app.use((err: any, _req: any, res: any, _next: any) => {
measureCtx.warn(err)
if (err instanceof ApiError) {
res.status(err.code).send({ code: err.code, message: err.message })
return
}
res.status(500).send(err.message?.length > 0 ? { message: err.message } : err)
})
return {
app,
close: () => {
void storageAdapter.close()
}
}
}
async function createPlatformClient (token: string): Promise<Client> {
setMetadata(client.metadata.ClientSocketFactory, (url) => {
return new WebSocket(url, {
headers: {
'User-Agent': process.env.SERVICE_ID
}
}) as never as ClientSocket
})View on GitHub (pinned to 63e28dc964)
Solutions
- Inspect the response body: if it has { code, message } it is an ApiError — act on that code; otherwise check server logs (measureCtx.warn) for the full stack.
- Ensure the request token is well-formed and current (decodeToken throws on garbage), and re-login if expired.
- Check storage adapter configuration/health if the 500 follows an upload/download path.
- If the response is the raw error object (no message), check Analytics for the serialized error to find the root cause.
Example fix
// before (empty-message error returned as raw object)
throw new Error('')
// after
throw new ApiError(400, 'Missing required parameters') Defensive patterns
Strategy: type-guard
Validate before calling
// client: check token shape before calling export APIs
if (typeof token !== 'string' || token.split('.').length !== 3) {
throw new Error('malformed token — obtain a fresh one from login')
} Type guard
function isApiErrorBody(body: unknown): body is { code: number; message: string } {
return typeof body === 'object' && body !== null &&
typeof (body as any).code === 'number' && typeof (body as any).message === 'string'
} Try / catch
const res = await exportApi.call(endpoint, payload)
if (!res.ok) {
const body = await res.json().catch(() => null)
if (isApiErrorBody(body)) throw new ApiError(body.code, body.message) // server-side ApiError
throw new Error(body?.message ?? `export service 500: ${res.status}`)
} Prevention
- Validate tokens are well-formed JWTs before each service call
- Differentiate ApiError responses ({ code, message }) from generic 500s in client handling
- Re-login on 401-class errors instead of retrying with the same token
- Report raw 500 bodies (no message) to support with the request ID/time
When it happens
Trigger: Any export HTTP request whose handler throws a non-ApiError: decodeToken failures on malformed tokens, storage adapter errors, unexpected exceptions in route logic, or async errors forwarded to next(err).
Common situations: Malformed/expired auth tokens hitting decodeToken, storage adapter connectivity problems, programming bugs (undefined access, bad params not caught as ApiError), and 500s with empty error messages returning the raw err object.
Related errors
- err.message?.length > 0 ? err.message : 'Internal Server Err
- response.statusText
- ${errorBody?.error}
- Request failed
- ${error.error ?? text}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/0865edc12cf66c74.
Report an issue: GitHub.