fix: audit replay with actual outcome, not premature SUCCESS
Replay audit log now records the agent's reply status (SUCCESS/FAILURE), message, and error details. Timeout and internal errors are also logged as FAILURE with the cause. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -233,19 +233,30 @@ public class AgentCommandController {
|
|||||||
CompletableFuture<CommandReply> future = registryService.addCommandWithReply(
|
CompletableFuture<CommandReply> future = registryService.addCommandWithReply(
|
||||||
id, CommandType.REPLAY, payloadJson);
|
id, CommandType.REPLAY, payloadJson);
|
||||||
|
|
||||||
auditService.log("replay_exchange", AuditCategory.AGENT, id,
|
Map<String, Object> auditDetails = new LinkedHashMap<>();
|
||||||
Map.of("routeId", request.routeId(),
|
auditDetails.put("routeId", request.routeId());
|
||||||
"originalExchangeId", request.originalExchangeId() != null ? request.originalExchangeId() : ""),
|
if (request.originalExchangeId() != null) {
|
||||||
AuditResult.SUCCESS, httpRequest);
|
auditDetails.put("originalExchangeId", request.originalExchangeId());
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CommandReply reply = future.orTimeout(30, TimeUnit.SECONDS).join();
|
CommandReply reply = future.orTimeout(30, TimeUnit.SECONDS).join();
|
||||||
|
auditDetails.put("replyStatus", reply.status());
|
||||||
|
auditDetails.put("replyMessage", reply.message() != null ? reply.message() : "");
|
||||||
|
auditService.log("replay_exchange", AuditCategory.AGENT, id, auditDetails,
|
||||||
|
"SUCCESS".equals(reply.status()) ? AuditResult.SUCCESS : AuditResult.FAILURE, httpRequest);
|
||||||
return ResponseEntity.ok(new ReplayResponse(reply.status(), reply.message(), reply.data()));
|
return ResponseEntity.ok(new ReplayResponse(reply.status(), reply.message(), reply.data()));
|
||||||
} catch (CompletionException e) {
|
} catch (CompletionException e) {
|
||||||
if (e.getCause() instanceof TimeoutException) {
|
if (e.getCause() instanceof TimeoutException) {
|
||||||
|
auditDetails.put("error", "timeout");
|
||||||
|
auditService.log("replay_exchange", AuditCategory.AGENT, id, auditDetails,
|
||||||
|
AuditResult.FAILURE, httpRequest);
|
||||||
return ResponseEntity.status(HttpStatus.GATEWAY_TIMEOUT)
|
return ResponseEntity.status(HttpStatus.GATEWAY_TIMEOUT)
|
||||||
.body(new ReplayResponse("FAILURE", "Agent did not respond within 30 seconds", null));
|
.body(new ReplayResponse("FAILURE", "Agent did not respond within 30 seconds", null));
|
||||||
}
|
}
|
||||||
|
auditDetails.put("error", e.getCause().getMessage());
|
||||||
|
auditService.log("replay_exchange", AuditCategory.AGENT, id, auditDetails,
|
||||||
|
AuditResult.FAILURE, httpRequest);
|
||||||
log.error("Error awaiting replay reply from agent {}", id, e);
|
log.error("Error awaiting replay reply from agent {}", id, e);
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
.body(new ReplayResponse("FAILURE", "Internal error: " + e.getCause().getMessage(), null));
|
.body(new ReplayResponse("FAILURE", "Internal error: " + e.getCause().getMessage(), null));
|
||||||
|
|||||||
Reference in New Issue
Block a user