From 19b50090101fa9823cdd67386fdad4ced2071a59 Mon Sep 17 00:00:00 2001 From: Jordan Ramos Date: Fri, 22 May 2026 11:51:10 -0600 Subject: [PATCH] =?UTF-8?q?Improve=20FP=20workflow=20error=20messages=20?= =?UTF-8?q?=E2=80=94=20include=20Ivanti=20API=20response=20body?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the Ivanti API returns a non-success status, the error message now includes the actual response body from Ivanti instead of just the HTTP status code. This makes troubleshooting much easier since you can see what Ivanti rejected (e.g. invalid field, too many attachments, malformed request). --- backend/routes/ivantiFpWorkflow.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/backend/routes/ivantiFpWorkflow.js b/backend/routes/ivantiFpWorkflow.js index 3384bd9..523ad32 100644 --- a/backend/routes/ivantiFpWorkflow.js +++ b/backend/routes/ivantiFpWorkflow.js @@ -281,8 +281,19 @@ function createIvantiFpWorkflowRouter() { if (createResult.status !== 200 && createResult.status !== 201 && createResult.status !== 202) { const errorMap = { 401: 'Ivanti API key is invalid or missing.', 419: 'API key lacks workflow creation permissions.', 429: 'Ivanti API rate limit reached.' }; - const errorMsg = errorMap[createResult.status] || `Workflow creation failed: ${createResult.status}`; - logAudit({ userId: req.user.id, username: req.user.username, action: 'ivanti_fp_workflow_failed', entityType: 'ivanti_workflow', details: { error: errorMsg, status: createResult.status, findingIds }, ipAddress: req.ip }); + let errorMsg = errorMap[createResult.status]; + if (!errorMsg) { + // Try to extract detail from the Ivanti response body + let bodyDetail = ''; + try { + const parsed = JSON.parse(createResult.body); + bodyDetail = parsed.message || parsed.error || parsed.detail || JSON.stringify(parsed); + } catch (_) { + bodyDetail = (createResult.body || '').slice(0, 500); + } + errorMsg = `Workflow creation failed (${createResult.status}): ${bodyDetail || 'No details returned by Ivanti API.'}`; + } + logAudit({ userId: req.user.id, username: req.user.username, action: 'ivanti_fp_workflow_failed', entityType: 'ivanti_workflow', details: { error: errorMsg, status: createResult.status, responseBody: (createResult.body || '').slice(0, 1000), findingIds }, ipAddress: req.ip }); return res.status(createResult.status === 429 ? 429 : 502).json({ success: false, error: errorMsg, step: 'create_workflow' }); }