Skip to content

ArcpClient.listJobs wraps checked exceptions in raw RuntimeException, hiding cause and breaking caller error handling #57

@nficano

Description

@nficano

In arcp-client/src/main/java/dev/arcp/client/ArcpClient.java the listJobs method around line 155 catches ExecutionException | InterruptedException | TimeoutException and rethrows them as a bare new RuntimeException("list_jobs failed", e) on line 165. This is the textbook anti-pattern for exception handling: callers cannot pattern-match the wrapped cause without instanceof gymnastics, the original stack trace is buried, and an InterruptedException is silently consumed without restoring the interrupt flag on the current thread. The result: a caller that wants to distinguish "server timed out" from "thread was interrupted" from "server returned an ArcpException" cannot, and downstream code that polls Thread.interrupted() will not see the interrupt that listJobs swallowed.\n\nThe same anti-pattern shows up in connect at line 133: an ExecutionException is rethrown as an IllegalStateException with no preservation of whether the underlying failure was an ArcpException, an IOException, or a transport error.\n\nFix prompt: In arcp-client/src/main/java/dev/arcp/client/ArcpClient.java rewrite listJobs to declare and throw the relevant typed exceptions. Specifically: re-declare throws InterruptedException, TimeoutException, ArcpException, restore the interrupt flag with Thread.currentThread().interrupt() in the InterruptedException catch then rethrow, propagate TimeoutException directly, and for ExecutionException unwrap the cause — if it is an ArcpException, rethrow it; otherwise wrap in a focused IllegalStateException whose message names the operation. Apply the same pattern to connect(Duration). Update any callers in arcp-client/src/test (RuntimeErrorMappingTest, SmokeRoundTripTest) and the examples directory to handle the new declared exceptions. The change is API-breaking but correct; for a 1.0.0-SNAPSHOT this is the moment to do it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    code-qualityCode quality, maintainability, and API designseverity:mediumMedium severity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions