{"record":{"id":"8c8a5b8610bcde11","repo":"hcengineering/platform","slug":"err-message-fallback-internal-server-error","errorCode":null,"errorMessage":"err.message (fallback: 'Internal Server Error')","messagePattern":"err\\.message \\(fallback: 'Internal Server Error'\\)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"services/backup/backup-api-pod/src/server.ts","lineNumber":390,"sourceCode":"      'File too large' // happens when the file exceeds the limit set by express-fileupload\n    ]\n\n    return !ignoreMessages.includes(err.message)\n  }\n\n  app.use((err: any, _req: any, res: any, _next: any) => {\n    ctx.error(err.message, { code: err.code, message: err.message })\n    if (err instanceof ApiError) {\n      res.status(err.code).send({ code: err.code, message: err.message })\n      return\n    }\n\n    // do not send some errors to analytics\n    if (sendErrorToAnalytics(err)) {\n      Analytics.handleError(err)\n    }\n\n    res.status(500).json({ message: err.message?.length > 0 ? err.message : 'Internal Server Error' })\n  })\n\n  app.get('/api/v1/statistics', (req, res) => {\n    try {\n      const token = req.query.token as string\n      const payload = decodeToken(token)\n      const admin = payload.extra?.admin === 'true'\n      res.setHeader('Content-Type', 'application/json')\n      res.setHeader('Connection', 'keep-alive')\n      res.setHeader('Keep-Alive', 'timeout=5')\n      res.setHeader('Cache-Control', cacheControlNoCache)\n\n      const json = JSON.stringify({\n        metrics: metricsAggregate((ctx as any).metrics),\n        statistics: {\n          cpu: getCPUInfo(),\n          memory: getMemoryInfo()\n        },","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/backup/backup-api-pod/src/server.ts#L372-L408","documentation":"The global Express error middleware logs the error, reports it to Analytics (unless its message is in the ignore list), and responds 500 with a JSON body whose message is err.message when non-empty, otherwise 'Internal Server Error'. It handles errors from middleware/routes other than the backup handler, e.g. JSON body parsing failures or ApiError thrown elsewhere.","triggerScenarios":"Malformed JSON in a request body exceeding or failing express.json parsing, thrown ApiError instances with codes, or any uncaught synchronous error in middleware (excluding the handled /api/backup route).","commonSituations":"Clients posting invalid JSON to endpoints on this service, oversized payloads beyond the 50mb limit, or unexpected bugs in middleware surfacing as 500 with the raw error message.","solutions":["Read the JSON body's message field — it contains the original err.message with the root cause","Fix the request payload (valid JSON, within the 50mb body limit)","Check server logs/Analytics for the full stack trace of the reported error","If the message leaks internals, wrap known failures in ApiError with a proper code"],"exampleFix":"// before\nres.status(500).json({ message: err.message?.length > 0 ? err.message : 'Internal Server Error' })\n// after\nconst msg = err instanceof ApiError ? err.message : 'Internal Server Error'\nres.status(500).json({ message: msg })","handlingStrategy":"try-catch","validationCode":"// send only valid, reasonably sized JSON bodies\nJSON.parse(payload) // throws early client-side on malformed JSON\nif (payload.length > 50 * 1024 * 1024) throw new Error('Body exceeds 50mb limit')","typeGuard":"function isApiErrorBody(body: unknown): body is { message: string } {\n  return typeof body === 'object' && body !== null && typeof (body as any).message === 'string'\n}","tryCatchPattern":"const res = await fetch(url, options)\nif (res.status === 500) {\n  const body = await res.json().catch(() => ({ message: 'Internal Server Error' }))\n  throw new Error(body.message)\n}","preventionTips":["Validate JSON payloads before posting","Keep request bodies under the 50mb express.json limit","Use ApiError with proper codes so clients get structured errors","Monitor Analytics for recurring 500 messages"],"tags":["http-500","error-handling","express"],"backgroundTag":"internal-server-error","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}