fix(reporter): PasteBin upload - timeout, missing Jackson dep, silent failures - #70
fix(reporter): PasteBin upload - timeout, missing Jackson dep, silent failures#70soloturn wants to merge 6 commits into
Conversation
Found while manually testing the reporter dialog: clicking "PasteBin" disabled the button, showed "please wait", and never resolved either way. PastebinUploadRunnable.call() makes a real HTTP POST via jpastebin with no timeout of its own, and UploadPanel.upload() just ran it on a bare thread and waited unboundedly for callable.call() to return - a slow or unreachable server left no way to tell "still working" from "will never finish". upload() now submits to an ExecutorService and waits at most 30s (configurable via a package-private constructor for tests) via future.get(timeout, SECONDS), cancelling the future and reporting a clear "Upload timed out after 30s" failure if it's not done by then. The wait-and-dispatch logic is split into a small static method, awaitUpload(), that's plain Future/Consumer plumbing with no Swing dependency - lets UploadPanelTest exercise the timeout, success, and underlying-failure-unwrapped-from-ExecutionException paths directly against real Futures, without a button-click harness. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Clicking "PasteBin" threw NoClassDefFoundError: com/fasterxml/jackson/core/type/TypeReference the first time it actually reached a Jackson class - reproduced directly by calling PastebinUploadRunnable.call() outside the dialog. jpastebin's own embedded META-INF/maven/org/jpastebin/pom.xml (inside the jar) pins jackson-databind/jackson-core/jackson-annotations 2.9.7, but the POM Gradle actually resolves for org:jpastebin:1.0.1 from the JBoss repo is an empty Nexus-generated stub with no <dependencies> at all - so Gradle never pulled Jackson in. Declares all three explicitly via the jackson-bom platform rather than three separately-pinned versions: jackson-annotations renumbered its own versioning away from core/databind's x.y.z scheme starting at 2.20, so hand-pinning all three to the same string breaks depending on which release line you pick. The BOM keeps them resolvable together regardless. 2.9.7 is a 2018 release with known CVEs; Jackson's 2.x line keeps this level of API (ObjectMapper, TypeReference, annotations) stable, so the current release is a safe drop-in rather than matching jpastebin's old pin. Verified end to end: a direct call to PastebinUploadRunnable now succeeds against the real API instead of throwing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
uploadFailed() only ever showed a JOptionPane - nothing else in this codebase logs upload failures anywhere. That popup reaches whoever happens to be watching the screen at that exact moment and leaves no trace at all once dismissed; whoever launched the process (a script, a supervisor, a developer tailing output) has no way to find out what happened after the fact. This is exactly what made the Jackson NoClassDefFoundError above hard to pin down in the first place - it only ever appeared as a popup. e.printStackTrace(System.err) now runs unconditionally before the dialog, on the same thread, so it can't get lost even if the JOptionPane is dismissed instantly. New package-private uploadForTesting() hook (bypasses the real ActionListener/network call so UploadPanelFailureLoggingTest can drive a failure directly) plus the same GlobalProperties NPE guard used elsewhere in this repo (needed just to construct GlobalProperties() in cr-core's own test classpath - see the sibling PRs). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…nto soloturn-pastebin-upload-fixes
…es' into soloturn-pastebin-upload-fixes # Conflicts: # cr-core/src/main/java/org/terasology/crashreporter/pages/UploadPanel.java
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Re: @BenjaminAmos's comment on #64 (now here) about tests reaching out to external URLs - clarifying, since that PR's gone: neither
So these are already fully offline and deterministic; nothing to change on that front. Happy to add an explicit comment in the test file noting this if it'd help future reviewers. |
Addresses @BenjaminAmos's review concern on #64 (now folded into this PR): these tests are already fully offline - PastebinUploadRunnable is never instantiated, and new URL(...) only parses a string, it never opens a connection. Making that explicit in the class javadoc so it isn't mistaken for a real network-touching test again. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Combines #64 and #65 - both PasteBin-upload fixes found while manually testing the reporter dialog, closing both in favor of this one.
Summary
1. Upload hung forever with no feedback
PastebinUploadRunnablemakes a real HTTP call with no timeout of its own.upload()now submits to a daemon-thread executor and waits up to 30s (awaitUpload(), a plain Swing-free method so the timeout/exception-unwrapping logic is directly testable) before treating it as failed, instead of leaving the button disabled and the status label reading "please wait" forever with no way to tell "still working" from "will never finish".2.
NoClassDefFoundError: com/fasterxml/jackson/core/type/TypeReferenceReproduced directly by calling
PastebinUploadRunnable.call()outside the dialog.jpastebin's own embeddedMETA-INF/maven/org/jpastebin/pom.xml(inside the jar) pinsjackson-databind/jackson-core/jackson-annotations2.9.7, but the POM Gradle actually resolves fororg:jpastebin:1.0.1from the JBoss repo is an empty Nexus-generated stub with no<dependencies>at all - so Gradle never pulled Jackson in, and it only ever surfaced the moment someone clicked the button.Declared all three explicitly via the
jackson-bomplatform rather than three separately-pinned versions:jackson-annotationsrenumbered its own versioning away from core/databind'sx.y.zscheme starting at 2.20, so hand-pinning all three to the same version string breaks depending which release line you pick.2.9.7is a 2018 release with known CVEs; Jackson's 2.x line keeps this level of API stable, so the current release is a safe drop-in.3. Upload failures only ever showed a
JOptionPane, with no trace anywhere elseWhich is exactly what made bug #2 hard to pin down in the first place - the exception only ever appeared as a popup, gone the moment it's dismissed, with nothing printed anywhere for whoever launched the process (a script, a supervisor, a developer tailing output) to find afterward.
uploadFailed()now unconditionally prints the exception to stderr before showing the dialog - the same fix applied to the timeout case above, since both funnel through the same failure path.Test plan
UploadPanelTest- drives the timeout path directly via the injectable timeout constructor andawaitUpload().UploadPanelFailureLoggingTest- drives a forced upload failure via a package-private test hook and asserts the exception lands on stderr../gradlew build- clean.Related
merge-train.