Report the real cause when jrunner fails
--strict means a failure now exits non-zero, so the returncode branch raises instead of _detect_silent_failure. That branch used raw stderr, whose first line is always the JVM's "Picked up JAVA_TOOL_OPTIONS: ..." banner (_subprocess_env sets JAVA_TOOL_OPTIONS to keep jt400 headless). Every failed run would therefore have recorded that banner in run_log instead of the actual error — a regression against the old path, which extracted the exception header. _error_message strips the banner and prefers the Java exception header: org.postgresql.util.PSQLException: ERROR: relation "..." does not exist org.postgresql.util.PSQLException: ERROR: syntax error at or near "SELEKT" Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
002deb8ad6
commit
63e900466c
@ -158,7 +158,7 @@ def query(
|
||||
_unlink_quietly(sql_path, pass_path)
|
||||
|
||||
if r.returncode != 0:
|
||||
raise JrunnerError(r.stderr.strip() or r.stdout.strip(),
|
||||
raise JrunnerError(_error_message(r.stdout, r.stderr),
|
||||
stdout=r.stdout, stderr=r.stderr)
|
||||
silent = _detect_silent_failure(r.stdout, r.stderr)
|
||||
if silent:
|
||||
@ -250,7 +250,7 @@ def migrate(
|
||||
_unlink_quietly(sql_path, pass_path)
|
||||
|
||||
if proc.returncode != 0:
|
||||
raise JrunnerError(stderr.strip() or stdout.strip(),
|
||||
raise JrunnerError(_error_message(stdout, stderr),
|
||||
stdout=stdout, stderr=stderr)
|
||||
silent = _detect_silent_failure(stdout, stderr)
|
||||
if silent:
|
||||
@ -317,6 +317,26 @@ def _parse_row_count(text: str) -> int | None:
|
||||
# nearly every failure site (see jrunner.java). Detect those by scanning
|
||||
# for a Java stack-trace signature so callers don't treat silent failures
|
||||
# as success.
|
||||
_JVM_NOISE_RE = re.compile(r"^Picked up JAVA_TOOL_OPTIONS:.*$", re.M)
|
||||
|
||||
|
||||
def _error_message(stdout: str, stderr: str) -> str:
|
||||
"""Best single-line cause for a failed jrunner call.
|
||||
|
||||
The JVM prints "Picked up JAVA_TOOL_OPTIONS: ..." as the first stderr line
|
||||
whenever JAVA_TOOL_OPTIONS is set (which _subprocess_env always does, to
|
||||
keep jt400 headless), so raising raw stderr surfaces that banner instead of
|
||||
the actual error. Prefer the Java exception header, which names the real
|
||||
failure, and fall back to whatever output remains once the banner is gone.
|
||||
"""
|
||||
cleaned_err = _JVM_NOISE_RE.sub("", stderr or "").strip()
|
||||
cleaned_out = _JVM_NOISE_RE.sub("", stdout or "").strip()
|
||||
m = _EXCEPTION_HEADER_RE.search(cleaned_err) or _EXCEPTION_HEADER_RE.search(cleaned_out)
|
||||
if m:
|
||||
return m.group(0).strip()
|
||||
return cleaned_err or cleaned_out or "jrunner failed with no output"
|
||||
|
||||
|
||||
_STACK_FRAME_RE = re.compile(r"^\s*at [\w.$<>]+\([^)\n]*\.java:\d+\)", re.M)
|
||||
_EXCEPTION_HEADER_RE = re.compile(
|
||||
r"^(?:[\w.$]+\.)*[\w$]+(?:Exception|Error)(?::[^\n]*)?$", re.M)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user