theonedev/onedev · error · ExplicitException

Http request failed (url: %s, status code: %d, error message

Error message

Http request failed (url: %s, status code: %d, error message: %s)

What it means

JerseyUtils.get performs a GET against an API endpoint expecting HTTP 200 and a JSON body. On any non-200 status with a non-blank error body, it throws ExplicitException formatted with the url, status code, and server-provided error message. ExplicitException indicates an anticipated, user-facing failure of the remote API call.

Source

Thrown at server-core/src/main/java/io/onedev/server/util/JerseyUtils.java:41

				return String.format("Http request failed (url: %s, status code: %d, error message: %s)", 
						url, status, errorMessage);
			} else {
				return String.format("Http request failed (url: %s, status code: %d)", url, status);
			}
		} else {
			return null;
		}
	}
	
	public static JsonNode get(Client client, String apiEndpoint, TaskLogger logger) {
		WebTarget target = client.target(apiEndpoint);
		Invocation.Builder builder =  target.request();
		try (Response response = builder.get()) {
			int status = response.getStatus();
			if (status != 200) {
				String errorMessage = response.readEntity(String.class);
				if (StringUtils.isNotBlank(errorMessage)) {
					throw new ExplicitException(String.format("Http request failed (url: %s, status code: %d, error message: %s)", 
							apiEndpoint, status, errorMessage));
				} else {
					throw new ExplicitException(String.format("Http request failed (status: %s)", status));
				}
			} 
			return response.readEntity(JsonNode.class);
		}
	}
	
	public static interface PageDataConsumer {
		
		void consume(List<JsonNode> pageData) throws InterruptedException;
		
	}
	
}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Read the error message in the exception — it comes from the remote server and usually states the real problem.
  2. Verify the apiEndpoint URL and resource id are correct and the resource exists.
  3. Check authentication: token validity, scopes, and permissions for the accessed resource.
  4. Retry on 429/5xx with backoff; check server health if 5xx persists.
  5. Use tools like curl on the same URL with the same credentials to reproduce outside the application.

Example fix

// before
JsonNode node = JerseyUtils.get("https://host/api/bad-resource"); // 404 with error body -> ExplicitException
// after
String url = "https://host/api/correct-resource"; // verify with curl first
JsonNode node = JerseyUtils.get(url);
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight
Response r = client.target(apiEndpoint).request().get();
// check credentials/URL beforehand; validate endpoint pattern
if (!apiEndpoint.startsWith("https://") ) throw new IllegalArgumentException("Invalid endpoint");

Try / catch

try {
    JsonNode node = JerseyUtils.get(apiEndpoint);
} catch (ExplicitException e) {
    // message contains url, status, and server error body — log and surface to user
    log.error("API GET failed: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling JerseyUtils.get(apiEndpoint) and receiving 4xx/5xx with a readable error body — invalid URL path, expired/insufficient credentials, missing permissions on the target resource, or server-side errors that include a message entity.

Common situations: Wrong endpoint or resource id (404), revoked access token (401/403), rate limiting (429) with error body, or upstream service 5xx responses carrying JSON/text error payloads.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/921a06bb388135cb. Report an issue: GitHub.