Skip to content

A crawl killed by a throwing progress callback reports Success - #159

Merged
xroche merged 2 commits into
masterfrom
fix/jniexc
Aug 23, 2026
Merged

A crawl killed by a throwing progress callback reports Success#159
xroche merged 2 commits into
masterfrom
fix/jniexc

Conversation

@xroche

@xroche xroche commented Aug 23, 2026

Copy link
Copy Markdown
Owner

A Java progress callback that throws leaves the exception pending on the crawl thread. The glue noticed it and asked the engine to stop, but never cleared it, so every JNI call after that point was illegal: the engine ticks the loop callback a few more times while it unwinds, and HTTrackLib_main then builds one last stats object and calls onRefresh again. A host probe that compiles the real htslibjni.c against an instrumented JNIEnv counts 72 such calls, starting at NewObject.

hts_main2 also returns 0 for an aborted mirror exactly as it does for a finished one, and the exception never reached Java, so the finish panel said "Success!". The glue now clears the exception where it detects it, keeps the first one in a global ref, leaves Java alone for the rest of the run, and rethrows it from HTTrackLib_main so the crawl runner reports the failure. On the same probe the illegal calls drop to zero, the exception reaches Java and main() returns -1; with nothing thrown, before and after behave identically. The three new unit tests only guard the shape of the C source, since nothing across the JNI boundary is reachable from a unit-test JVM.

xroche and others added 2 commits August 23, 2026 11:48
A Java progress callback that throws leaves the exception pending on the
crawl thread. htsshow_loop_internal noticed it and asked the engine to
stop, but never cleared it, so every JNI call after that point was
illegal: the engine ticks the loop callback a few more times while it
unwinds, and HTTrackLib_main then builds one last stats object and calls
onRefresh again. A host probe over the real glue, driven through an
instrumented JNIEnv, counts 72 such calls, starting at NewObject.

hts_main2 also returns 0 for an aborted mirror exactly as it does for a
finished one, and the exception never reached Java, so the finish panel
reported success. Clear it where it is detected, keep the first one in a
global ref, leave Java alone for the rest of the run, and rethrow it from
HTTrackLib_main so the crawl runner reports the failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
Review built the case and measured it: if NewGlobalRef fails under memory
pressure, pendingException stays null, the gate never arms, the fresh
OutOfMemoryError is left pending and the engine ticks on. That reproduces the
original 72 illegal calls, and is worse than master, which at least returned 0
from the callback and aborted.

capturePendingException now reports whether it saw an exception at all, and the
abort follows that rather than whether the throwable was kept. Under memory
pressure the run still ends; only the identity of the exception is lost, and
the caller falls back to reporting an IOException.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
@xroche
xroche merged commit ee7e28d into master Aug 23, 2026
6 checks passed
@xroche
xroche deleted the fix/jniexc branch August 23, 2026 14:05
xroche added a commit that referenced this pull request Aug 26, 2026
The engine moves to 26f24acb, the tagged 3.49.24. Nothing it changes reaches the
Android binary: the delta is the WebHTTrack server and the guide, and htsserver.c
is not in Android.mk. The docs bundle does ship, built from the pinned engine. It
now covers the reshot Android screenshots and the all-files-access and
notification steps the guide never described. The droid/* anchors Help deep-links
to are unchanged.

Release notes are rewritten for the round: the outcome fixes (#158, #159, #162,
#163, #169), the native-fault ones (#160, #165, #168), the storage warning (#155)
and the import prompt a fresh install could not answer (#164). The resume-offer
note claims only what #158 delivers, since markers already on disk are left alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant