hcengineering/platform · error
err.message?.length > 0 ? err.message : 'Internal Server Err
Error message
err.message?.length > 0 ? err.message : 'Internal Server Error'
What it means
This is the datalake Express global error-handling middleware. When any route handler throws or calls next(err) and the error is not an ApiError, it logs the error, reports it to Analytics (unless the message is a known client-abort case like 'Premature close' or 'File too large'), and responds 500 with err.message, or the literal 'Internal Server Error' when the message is empty or undefined. It exists as the last-resort handler so unhandled server errors always produce a JSON response instead of a hung request.
Source
Thrown at services/datalake/pod-datalake/src/server.ts:324
'File too large' // happens when the file exceeds the limit set by express-fileupload
]
return !ignoreMessages.includes(err.message)
}
app.use((err: any, _req: any, res: any, _next: any) => {
ctx.error(err.message, { code: err.code, message: err.message })
if (err instanceof ApiError) {
res.status(err.code).send({ code: err.code, message: err.message })
return
}
// do not send some errors to analytics
if (sendErrorToAnalytics(err)) {
Analytics.handleError(err)
}
res.status(500).json({ message: err.message?.length > 0 ? err.message : 'Internal Server Error' })
})
app.get('/api/v1/statistics', (req, res) => {
try {
const token = req.query.token as string
const payload = decodeToken(token)
const admin = payload.extra?.admin === 'true'
res.setHeader('Content-Type', 'application/json')
res.setHeader('Connection', 'keep-alive')
res.setHeader('Keep-Alive', 'timeout=5')
res.setHeader('Cache-Control', cacheControlNoCache)
const json = JSON.stringify({
metrics: metricsAggregate((ctx as any).metrics),
statistics: {
cpu: getCPUInfo(),
memory: getMemoryInfo()
},View on GitHub (pinned to 63e28dc964)
Solutions
- Check the server logs at the same timestamp (ctx.error with code/message) to find the root-cause error thrown by the failing route.
- If the message is 'Premature close' / 'Unexpected end of form' / 'File too large', fix the client: complete or restart the upload, or raise the express-fileupload size limit.
- If it is a storage or network failure, verify object-storage connectivity and credentials, then retry the request.
- If the message is 'Internal Server Error', inspect Analytics entries for the underlying error object, since no useful message reached the response.
Example fix
// before (client ignores aborts and gets opaque 500s)
await fetch(uploadUrl, { method: 'PUT', body: stream, signal: undefined })
// after (client handles aborts explicitly)
const ctrl = new AbortController()
try {
await fetch(uploadUrl, { method: 'PUT', body: stream, signal: ctrl.signal })
} catch (e) {
if (ctrl.signal.aborted) console.warn('upload cancelled')
else throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
// client: ensure upload stream is complete and within size limits before sending
if (fileSize > MAX_UPLOAD_SIZE) throw new Error('File exceeds server upload limit')
if (stream.destroyed || stream.readableEnded) throw new Error('Upload stream already closed') Type guard
function isApiError(e: unknown): e is { code: number; message: string } {
return typeof e === 'object' && e !== null && 'code' in e && typeof (e as any).code === 'number'
} Try / catch
try {
const res = await fetch(datalakeUrl, opts)
if (!res.ok) {
const body = await res.json().catch(() => ({}))
if (res.status === 500 && body.message === 'Internal Server Error') throw new Error('datalake 500: check server logs')
throw new Error(body.message ?? `datalake ${res.status}`)
}
} catch (e) {
// retry idempotent reads; surface message; treat aborts ('Premature close') as client-cancelled
} Prevention
- Keep uploads within the server's express-fileupload size limit
- Do not abort requests mid-upload; use resumable uploads for large files
- Retry with backoff on 500 for idempotent operations
- Monitor datalake server logs for the root-cause message paired with each 500
When it happens
Trigger: Any datalake HTTP request (uploads, workspace/object routes, statistics) whose handler throws a non-ApiError: malformed multipart bodies, storage adapter failures, unexpected exceptions in route logic, or body-parsing errors forwarded via next(err).
Common situations: S3/blob storage outages mid-upload, express-fileupload limits ('File too large'), clients aborting uploads ('Unexpected end of form', 'Premature close'), or bugs in a handler throwing undefined-message errors.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- err.message
- Failed to initialize multipart upload
- Failed to complete multipart upload
- Failed to reject multipart upload
- Upload failed:
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/adba73a2fa140114.
Report an issue: GitHub.