From 32e4d3b0b1202cbd8564d2222f931d9eb06c72cf Mon Sep 17 00:00:00 2001 From: zouyx Date: Sun, 19 Jul 2026 00:10:15 +0800 Subject: [PATCH 1/2] fix(dashscope): preserve SSE error response body --- .../model/dashscope/DashScopeHttpClient.java | 15 ++++++++++----- .../model/dashscope/DashScopeHttpClientTest.java | 5 ++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java index 6adce7e2f2..0456515998 100644 --- a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java +++ b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java @@ -277,8 +277,10 @@ public Flux stream( if (finalEncryptionContext != null) { data = decryptResponse(data, finalEncryptionContext); } - return JsonUtils.getJsonCodec() - .fromJson(data, DashScopeResponse.class); + return new ParsedStreamResponse( + data, + JsonUtils.getJsonCodec() + .fromJson(data, DashScopeResponse.class)); } catch (JsonException e) { log.warn( "Failed to parse SSE data: {}. Error: {}", @@ -288,15 +290,16 @@ public Flux stream( return null; } }) - .filter(response -> response != null) + .filter(streamResponse -> streamResponse != null) .handle( - (response, sink) -> { + (streamResponse, sink) -> { + DashScopeResponse response = streamResponse.response(); if (response.isError()) { sink.error( new DashScopeHttpException( "DashScope API error: " + response.getMessage(), response.getCode(), - null)); + streamResponse.responseBody())); } else { sink.next(response); } @@ -834,6 +837,8 @@ public DashScopeHttpClient build() { } } + private record ParsedStreamResponse(String responseBody, DashScopeResponse response) {} + /** * Exception thrown when DashScope HTTP operations fail. */ diff --git a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java index 0d327bf690..1f9e8090e5 100644 --- a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java +++ b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java @@ -647,7 +647,10 @@ void testStreamErrorHandling() { && dashScopeHttpException.getErrorCode().equals(errorCode) && dashScopeHttpException .getMessage() - .equals("DashScope API error: " + errorMessage)) + .equals("DashScope API error: " + errorMessage) + && dashScopeHttpException + .getResponseBody() + .contains("\"request_id\":\"request_id_123\"")) .verify(); } From 1cd5194e615f4314094442c7c308a98d8af20609 Mon Sep 17 00:00:00 2001 From: zouyx Date: Sun, 19 Jul 2026 18:08:21 +0800 Subject: [PATCH 2/2] fix(dashscope): ignore malformed SSE events --- .../model/dashscope/DashScopeHttpClient.java | 18 +++++++++--------- .../dashscope/DashScopeHttpClientTest.java | 13 +++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java index 0456515998..613a0776bb 100644 --- a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java +++ b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/main/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClient.java @@ -270,27 +270,27 @@ public Flux stream( .build(); return transport.stream(httpRequest) - .map( - data -> { + .handle( + (data, sink) -> { try { // Decrypt response if encryption is enabled if (finalEncryptionContext != null) { data = decryptResponse(data, finalEncryptionContext); } - return new ParsedStreamResponse( - data, - JsonUtils.getJsonCodec() - .fromJson(data, DashScopeResponse.class)); + sink.next( + new ParsedStreamResponse( + data, + JsonUtils.getJsonCodec() + .fromJson( + data, + DashScopeResponse.class))); } catch (JsonException e) { log.warn( "Failed to parse SSE data: {}. Error: {}", data, e.getMessage()); - // Return null and filter out later - return null; } }) - .filter(streamResponse -> streamResponse != null) .handle( (streamResponse, sink) -> { DashScopeResponse response = streamResponse.response(); diff --git a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java index 1f9e8090e5..30515f0677 100644 --- a/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java +++ b/agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-dashscope/src/test/java/io/agentscope/extensions/model/dashscope/DashScopeHttpClientTest.java @@ -654,6 +654,19 @@ void testStreamErrorHandling() { .verify(); } + @Test + void testStreamIgnoresMalformedSseData() { + mockServer.enqueue( + new MockResponse() + .setResponseCode(200) + .setBody("data: malformed-json\\n\\n") + .setHeader("Content-Type", "text/event-stream")); + + DashScopeRequest request = createTestRequest("qwen-plus", "test"); + + StepVerifier.create(client.stream(request, null, null, null)).verifyComplete(); + } + @Test void testHeaderOverride() throws Exception { mockServer.enqueue(