fix(cpg): report the line that names an engine failure, not its frames

Every PHP failure logged `cpg batch taint failed: dure1.java:10)`, which is the
middle of a stack frame and says nothing. A trace puts its exception on the FIRST
line and frames after it, and the backend logged the last 400 characters, so the
cause was discarded and the noise kept. Four investigations were spent on that.

Failures now report the leading non-frame lines, which is where the exception and
its message are, with the frames dropped. A control asserts an OutOfMemoryError
survives while a frame does not, and that a timeout and an empty exit stay
distinguishable.

1,411 tests passed, nine skipped.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-09-18 17:58:42 +02:00
co-authored by Claude Opus 5
parent dfc29238b5
commit 6089c67bf6
2 changed files with 32 additions and 2 deletions
+13
View File
@@ -1217,3 +1217,16 @@ def test_a_batch_no_part_can_answer_is_still_unavailable(tmp_path, monkeypatch):
graph.write_bytes(b"graph")
# None means "could not ask", which must never become an empty answer.
assert backend.query_batch(graph, "taint", {str(i): {"file": f"f{i}.php"} for i in range(8)}) is None
def test_an_engine_failure_reports_the_line_that_names_the_cause(tmp_path, monkeypatch):
"""A stack trace's exception is on its first line; logging the tail reports frames only."""
from openultrasast.cpg.backend import JoernBackend, _engine_failure
trace = "java.lang.OutOfMemoryError: Java heap space\n\tat foo.Bar.baz(Bar.java:10)\n\tat x.Procedure1.java:10)"
named = _engine_failure(subprocess.CompletedProcess(["joern"], 1, "", trace))
assert "OutOfMemoryError" in named and "Java heap space" in named
assert "Bar.java:10" not in named, "frames are noise; the cause is not"
assert _engine_failure(None) == "timeout"
assert "no output" in _engine_failure(subprocess.CompletedProcess(["joern"], 3, "", ""))
assert isinstance(JoernBackend(), JoernBackend)