From 5209b3bda705ac29b36092dd9bf605ef07b22228 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Mon, 5 Oct 2026 13:18:16 +0200 Subject: [PATCH] [Fix #1737] Calculate communication status error code from cause. Fix #1737 Signed-off-by: Francisco Javier Tirado Sarti --- .../http/AbstractRequestExecutor.java | 19 +++++++++++++++++-- .../io/serverlessworkflow/types/Errors.java | 3 +-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AbstractRequestExecutor.java b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AbstractRequestExecutor.java index e2a5d141d..83caf1789 100644 --- a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AbstractRequestExecutor.java +++ b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AbstractRequestExecutor.java @@ -31,10 +31,13 @@ import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status.Family; +import java.net.SocketTimeoutException; import java.net.URI; +import java.net.http.HttpTimeoutException; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeoutException; abstract class AbstractRequestExecutor implements RequestExecutor { @@ -79,15 +82,27 @@ private WorkflowModel doRequest( .application() .modelFactory() .fromAny(response.readEntity(converter.responseType())); - } catch (ProcessingException | IllegalStateException ex) { + } catch (ProcessingException ex) { throw new WorkflowException( - WorkflowError.communication(Errors.DATA.status(), task, ex).build(), ex); + WorkflowError.communication(errorCodeFromException(ex.getCause()), task, ex).build(), ex); } catch (WebApplicationException ex) { throw new WorkflowException( WorkflowError.communication(ex.getResponse().getStatus(), task, ex).build(), ex); } } + protected int errorCodeFromException(Throwable ex) { + while (ex != null) { + if (ex instanceof TimeoutException + || ex instanceof SocketTimeoutException + || ex instanceof HttpTimeoutException) { + return Errors.TIMEOUT.status(); + } + ex = ex.getCause(); + } + return Errors.COMMUNICATION.status(); + } + private void validateStatus(TaskContext task, Response response, HttpModelConverter converter) { Family statusFamily = response.getStatusInfo().getFamily(); if (statusFamily != SUCCESSFUL && (!this.redirect || statusFamily != REDIRECTION)) { diff --git a/types/src/main/java/io/serverlessworkflow/types/Errors.java b/types/src/main/java/io/serverlessworkflow/types/Errors.java index 2c2f25cb3..7097d7db4 100644 --- a/types/src/main/java/io/serverlessworkflow/types/Errors.java +++ b/types/src/main/java/io/serverlessworkflow/types/Errors.java @@ -85,9 +85,8 @@ public String toString() { } } - // ---- Standard catalog (defaults are conventional HTTP mappings; override if you prefer) ---- public static final Standard RUNTIME = new Standard("runtime", 500); - public static final Standard COMMUNICATION = new Standard("communication", 502); + public static final Standard COMMUNICATION = new Standard("communication", 500); public static final Standard AUTHENTICATION = new Standard("authentication", 401); public static final Standard AUTHORIZATION = new Standard("authorization", 403); public static final Standard DATA = new Standard("data", 422);