gnodet-bot commented on code in PR #29514:
URL: https://github.com/apache/camel/pull/29514#discussion_r4518979450


##########
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ChaosExplore.java:
##########
@@ -133,34 +144,58 @@ public Integer doCall() throws Exception {
             printer().printErr(started.error());
             return started.exitCode();
         }
-        printer().println("Let there be chaos: " + process.name() + " (pid " + 
process.pid() + "), "
+        String integration = displayName(process);
+        printer().println("Let there be chaos: " + integration + " (pid " + 
process.pid() + "), "
                           + 
TimeUtils.printDuration(started.reply().getLongOrDefault("budget", 0))
                           + (focus != null && !focus.isBlank() ? ", focus: " + 
focus : ""));
         int answer;
+        Ask ask = ask(process, integration);
         try {
-            answer = ask(process).doCall();
+            answer = ask.doCall();
         } catch (Exception e) {
             // the LLM fails with an exit code; anything else must not cost 
the report of what was explored so far
-            printer().printErr("camel ask failed: " + e.getMessage());
+            // an exception without a message is known by its type
+            printer().printErr("camel ask failed: " + (e.getMessage() != null 
? e.getMessage() : e.getClass().getSimpleName()));
             answer = CliExitCode.FAILURE;
         } finally {
             // the AI may have finished it already; else its rules go now
             ActionClient.execute(process, "chaos", root -> root.put("command", 
"explore-finish"), 10000);
         }
-        JsonObject exploration = 
ChaosExperimentRun.exploration(RuntimeHelper.readStatus(process.pid()));
+        JsonObject status = RuntimeHelper.readStatus(process.pid());
+        JsonObject exploration = ChaosExperimentRun.exploration(status);
         List<String> lines = journal(exploration);
         printer().println();
         lines.forEach(printer()::println);
+        if (save && exploration != null) {
+            Saved saved = save(Path.of("test", "chaos"), LocalDateTime.now(),
+                    new Run(integration, budget, focus, ask.usedModel, 
seed(status)), exploration, ask.lastAnswer,
+                    lines);
+            printer().println();
+            printer().println("Report: " + saved.report());
+            saved.scenarios().forEach(s -> printer().println("Scenario: " + s 
+ " (replay: camel run * --chaos=" + s + ")"));
+        }

Review Comment:
   💡 **`save()` IOException not handled gracefully.**
   
   The `save()` call is outside the try/catch that wraps `ask.doCall()`. If 
`Files.createDirectories()` or `Files.writeString()` fails (disk full, 
permission denied), the IOException propagates uncaught from `doCall()` as a 
raw Java exception — the user sees a stack trace rather than a readable error 
message like `"Could not save the report: ..."`. Consider wrapping the save 
block:
   
   ```suggestion
           try {
               if (save && exploration != null) {
                   Saved saved = save(Path.of("test", "chaos"), 
LocalDateTime.now(),
                           new Run(integration, budget, focus, ask.usedModel, 
seed(status)), exploration, ask.lastAnswer,
                           lines);
                   printer().println();
                   printer().println("Report: " + saved.report());
                   saved.scenarios().forEach(s -> printer().println("Scenario: 
" + s + " (replay: camel run * --chaos=" + s + ")"));
               }
           } catch (IOException e) {
               printer().printErr("Could not save the report: " + 
e.getMessage());
           }
   ```



##########
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/ToolRegistry.java:
##########
@@ -1005,6 +1006,13 @@ private static void registerChaosTools() {
                                     feed, args.get("body"), 
args.get("headers"), repeat,
                                     args.get("interval"))
                             : null;
+                    if (traffic != null) {
+                        // an experiment without messages says nothing: the AI 
gets the routes to feed instead
+                        String why = 
ChaosExperimentRun.checkFeed(ctx.readFullStatus(), feed);
+                        if (why != null) {
+                            throw new ToolExecutionException(why);
+                        }
+                    }

Review Comment:
   💡 **Minor: `checkFeed()` is called twice on the ToolRegistry path.**
   
   `checkFeed(ctx.readFullStatus(), feed)` is called here (pre-check in 
ToolRegistry), and then `checkFeed(integration.status(), feed.endpoint())` is 
called again inside `ChaosExperimentRun.run()` — each call to 
`integration.status()` is another `ctx.readFullStatus()` network round-trip. 
The guard inside `run()` is a defensive check for non-ToolRegistry callers 
(e.g. `CamelChaosExperimentAction`), but on the ToolRegistry path it results in 
two status reads. This is intentional defensive programming or a minor 
redundancy worth noting.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to