[BUG] azure-core-http-netty ignores response timeout when write timeout is disabled
Los mantenedores suelen responder en 1 día
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Describe the bug
With azure-core-http-netty 1.16.5, setting writeTimeout(Duration.ZERO) also prevents the configured response timeout from firing.
I reproduced this with a WireMock endpoint that matches the request body and delays its response by one second. With a 100 ms response timeout and write timeout disabled, the request succeeds after about one second. Setting a positive write timeout makes the same request time out after about 100 ms.
Disabling the write timeout should only disable the write timeout, not the response timeout.
Exception or Stack Trace
No SDK exception is thrown in the disabled-write case. The reproducing test fails with this assertion:
org.opentest4j.AssertionFailedError: Expected java.lang.RuntimeException to be thrown, but nothing was thrown.
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:152)
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:73)
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:35)
at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3128)
at AzureNettyResponseTimeoutWireMockTest.responseTimeoutShouldNotDependOnWriteTimeout(AzureNettyResponseTimeoutWireMockTest.java:53)
To Reproduce
- In a Java test project using
azure-core-http-netty:1.16.5and JUnit Jupiter, add the WireMock test dependency below if it is not already available. - Copy the test class below into
src/test/java/AzureNettyResponseTimeoutWireMockTest.java. - Run
mvn -Dtest=AzureNettyResponseTimeoutWireMockTest test(from the HTTP Netty module if using the SDK repository). - Observe that the
writeTimeoutMillis=0case fails because no exception is thrown; thewriteTimeoutMillis=5000control case passes with the expected SDK response-timeout exception. No Azure credentials or service are required.
Verified output:
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0
Maven exits with code 1 because the disabled-write case reproduces the bug.
Code Snippet
WireMock test dependency, if needed. The standalone artifact avoids changing the project's Jetty dependencies:
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock-standalone</artifactId>
<version>3.13.1</version>
<scope>test</scope>
</dependency>
import com.azure.core.http.HttpClient;
import com.azure.core.http.HttpMethod;
import com.azure.core.http.HttpRequest;
import com.azure.core.http.HttpResponse;
import com.azure.core.http.netty.NettyAsyncHttpClientBuilder;
import com.github.tomakehurst.wiremock.WireMockServer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.time.Duration;
import java.util.concurrent.TimeoutException;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class AzureNettyResponseTimeoutWireMockTest {
private WireMockServer wireMock;
@BeforeEach
void setUp() {
wireMock = new WireMockServer(wireMockConfig().bindAddress("127.0.0.1").dynamicPort());
wireMock.start();
wireMock.stubFor(post(urlEqualTo("/timeout"))
.withRequestBody(equalTo("payload"))
.willReturn(aResponse().withStatus(200).withFixedDelay(1_000)));
}
@AfterEach
void tearDown() {
if (wireMock != null) wireMock.stop();
}
@ParameterizedTest(name = "writeTimeoutMillis={0}")
@ValueSource(longs = {0, 5_000})
@Timeout(10)
void responseTimeoutShouldNotDependOnWriteTimeout(long writeTimeoutMillis) {
HttpClient client = new NettyAsyncHttpClientBuilder()
.writeTimeout(Duration.ofMillis(writeTimeoutMillis))
.responseTimeout(Duration.ofMillis(100))
.build();
HttpRequest request = new HttpRequest(HttpMethod.POST, "http://127.0.0.1:" + wireMock.port() + "/timeout")
.setBody("payload");
RuntimeException failure = assertThrows(RuntimeException.class, () -> {
try (HttpResponse ignored = client.send(request).block(Duration.ofSeconds(3))) {
// Returning normally means the configured response timeout did not fire.
}
});
Throwable root = failure;
while (root.getCause() != null) root = root.getCause();
assertInstanceOf(TimeoutException.class, root);
assertTrue(root.getMessage().contains("Channel response timed out"));
}
}
Only writeTimeout and responseTimeout are configured on the SDK client; all other client settings retain their defaults. The three-second blocking timeout is just a test safety bound, and the assertion specifically checks the SDK's response-timeout exception.
Expected behavior
Both parameterized cases should pass: with a 100 ms response timeout and a one-second server response delay, the SDK should throw a response-timeout exception whether the write timeout is enabled or disabled.
Screenshots
Not applicable.
Setup (please complete the following information):
- OS: macOS 26.5
- IDE: Not applicable; reproduced from the terminal using Maven.
- Library/Libraries:
com.azure:azure-core-http-netty:1.16.5com.azure:azure-core:1.58.1(SDK transitive dependency)io.projectreactor.netty:reactor-netty-http:1.2.18(SDK transitive dependency)org.junit.jupiter:junit-jupiter:5.13.4(test dependency)org.wiremock:wiremock-standalone:3.13.1(test dependency)
- Java version: Temurin OpenJDK 26.0.1+8. The reproduction compiles with Java release 17.
- App Server/Environment: Standalone Maven/JUnit test with a local HTTP server on
127.0.0.1; no application server or Azure service. - Frameworks: JUnit Jupiter and WireMock. No Spring Boot or other application framework.
The standalone reproduction uses the SDK's normal transitive dependencies. No NoClassDefFoundError or NoSuchMethodError occurs in this reproduction; a dependency version mismatch is not suspected.
Additional context
The suspected cause is in Azure SDK's own AzureSdkHandler, rather than Netty or Reactor Netty:
sdk/core/azure-core-http-netty/src/main/java/com/azure/core/http/netty/implementation/AzureSdkHandler.java
Source, lines 129-138: the write-completion listener is installed only when writeTimeoutMillis > 0 at line 129. That listener also calls startResponseTracking() at line 134. When write timeout is disabled, the branch at line 138 writes without installing this listener.
Information Checklist
- Bug Description Added
- Repro Steps Added
- Setup information Added
- Lenguaje dominante
- Java
- Estrellas
- 2.6k
- Forks
- 2.2k
- Merge medio
- 1 d 18 h
- PR fusionados (30 d)
- 231
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de Azure/azure-sdk-for-java
-
mgmt, in track 1 migration guide, call out that file-based authentication method is not recommendedQuizá libre de nuevo Un pull request para esta issue se cerró sin fusionarse. AbiertoAzure.Identity
Dificultad 1/5 Menos de una hora Aptitud para principiantes 74/100
Azure/azure-sdk-for-java#48894 ·
Los mantenedores suelen responder en 1 día
-
Azure.Core HttpClient
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
Azure/azure-sdk-for-java#50961 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Azure.Core.V2 clientcore
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Azure/azure-sdk-for-java#50936 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Paging extenisonsAbiertoclientcore
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
Azure/azure-sdk-for-java#50935 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Update Configuration handlingAbiertoclientcore
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Azure/azure-sdk-for-java#50934 · 1 reacción ·
Los mantenedores suelen responder en 1 día
Todos los issues de Azure/azure-sdk-for-java
Issues similares
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
-
[Bug]: REST API URL starting with "http" but no scheme (e.g. httpbin.org/get) is not given an http:// prefixPosiblemente ocupada @ItsDeadlyProgrammer la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
appsmithorg/appsmith#42471 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
code-maintenance
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
-
bug priority: medium Review effort [1-5]: 3 status: needs-triage type: bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
carlos-emr/carlos#5258 ·
Los mantenedores suelen responder en 1 día