| 275 | |
| 276 | /** Extract a meaningful error message from a Concur error response body. */ |
| 277 | export function extractSapConcurError(body: unknown, status: number): string { |
| 278 | if (body && typeof body === 'object') { |
| 279 | const obj = body as Record<string, unknown> |
| 280 | if (typeof obj.error === 'string' && obj.error.length > 0) { |
| 281 | const desc = typeof obj.error_description === 'string' ? `: ${obj.error_description}` : '' |
| 282 | return `${obj.error}${desc}` |
| 283 | } |
| 284 | if (typeof obj.message === 'string' && obj.message.length > 0) { |
| 285 | return obj.message |
| 286 | } |
| 287 | const errors = obj.errors |
| 288 | if (Array.isArray(errors) && errors.length > 0) { |
| 289 | return errors |
| 290 | .map((e) => { |
| 291 | if (e && typeof e === 'object') { |
| 292 | const eo = e as Record<string, unknown> |
| 293 | const code = typeof eo.errorCode === 'string' ? `[${eo.errorCode}] ` : '' |
| 294 | const msg = typeof eo.errorMessage === 'string' ? eo.errorMessage : '' |
| 295 | return `${code}${msg}`.trim() |
| 296 | } |
| 297 | return String(e) |
| 298 | }) |
| 299 | .filter(Boolean) |
| 300 | .join('; ') |
| 301 | } |
| 302 | } |
| 303 | if (typeof body === 'string' && body.length > 0) return body |
| 304 | return `Concur request failed with HTTP ${status}` |
| 305 | } |