Skip to content

Commit 4325d60

Browse files
author
kevin
committed
fix: standardize error handling with proper status codes and structured messages
1 parent 36905cb commit 4325d60

7 files changed

Lines changed: 275 additions & 22 deletions

File tree

src/main/java/com/alibaba/dashscope/audio/omni/OmniRealtimeConversation.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
// Copyright (c) Alibaba, Inc. and its affiliates.
22
package com.alibaba.dashscope.audio.omni;
33

4+
import com.alibaba.dashscope.common.PublicErrorDef;
5+
import com.alibaba.dashscope.common.Status;
6+
import com.alibaba.dashscope.exception.ApiException;
47
import com.alibaba.dashscope.exception.NoApiKeyException;
58
import com.alibaba.dashscope.protocol.DashScopeHeaders;
69
import com.alibaba.dashscope.protocol.okhttp.OkHttpClientFactory;
710
import com.alibaba.dashscope.utils.ApiKey;
811
import com.alibaba.dashscope.utils.Constants;
912
import com.alibaba.dashscope.utils.JsonUtils;
13+
import com.alibaba.dashscope.utils.StringUtils;
1014
import com.google.gson.Gson;
1115
import com.google.gson.GsonBuilder;
1216
import com.google.gson.JsonObject;
@@ -323,6 +327,31 @@ private Request buildConnectionRequest(
323327
if (baseWebSocketUrl != null) {
324328
url = baseWebSocketUrl;
325329
}
330+
// Validate URL before building request to provide clear error message
331+
if (url == null || url.isEmpty()) {
332+
throw new ApiException(
333+
Status.builder()
334+
.statusCode(PublicErrorDef.INVALID_URL.getStatusCode())
335+
.code(PublicErrorDef.INVALID_URL.getErrorCode())
336+
.message(
337+
StringUtils.format(
338+
"%s [detail=URL is null or empty]", PublicErrorDef.INVALID_URL.getErrorMsg()))
339+
.build());
340+
}
341+
// HttpUrl.parse() only supports http/https, convert ws/wss for validation
342+
String urlForValidation =
343+
url.replaceFirst("^ws://", "http://").replaceFirst("^wss://", "https://");
344+
HttpUrl parsedUrl = HttpUrl.parse(urlForValidation);
345+
if (parsedUrl == null) {
346+
throw new ApiException(
347+
Status.builder()
348+
.statusCode(PublicErrorDef.INVALID_URL.getStatusCode())
349+
.code(PublicErrorDef.INVALID_URL.getErrorCode())
350+
.message(
351+
StringUtils.format(
352+
"%s [detail=%s]", PublicErrorDef.INVALID_URL.getErrorMsg(), url))
353+
.build());
354+
}
326355
Request request = bd.url(url).build();
327356
return request;
328357
}

src/main/java/com/alibaba/dashscope/audio/protocol/AudioWebsocketRequest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.alibaba.dashscope.audio.protocol;
22

3+
import com.alibaba.dashscope.common.PublicErrorDef;
4+
import com.alibaba.dashscope.common.Status;
5+
import com.alibaba.dashscope.exception.ApiException;
36
import com.alibaba.dashscope.exception.NoApiKeyException;
47
import com.alibaba.dashscope.protocol.DashScopeHeaders;
58
import com.alibaba.dashscope.protocol.okhttp.OkHttpClientFactory;
69
import com.alibaba.dashscope.utils.ApiKey;
710
import com.alibaba.dashscope.utils.Constants;
11+
import com.alibaba.dashscope.utils.StringUtils;
812
import java.util.Map;
913
import java.util.concurrent.CountDownLatch;
1014
import java.util.concurrent.TimeUnit;
@@ -78,6 +82,31 @@ private Request buildConnectionRequest(
7882
if (baseWebSocketUrl != null) {
7983
url = baseWebSocketUrl;
8084
}
85+
// Validate URL before building request to provide clear error message
86+
if (url == null || url.isEmpty()) {
87+
throw new ApiException(
88+
Status.builder()
89+
.statusCode(PublicErrorDef.INVALID_URL.getStatusCode())
90+
.code(PublicErrorDef.INVALID_URL.getErrorCode())
91+
.message(
92+
StringUtils.format(
93+
"%s [detail=URL is null or empty]", PublicErrorDef.INVALID_URL.getErrorMsg()))
94+
.build());
95+
}
96+
// HttpUrl.parse() only supports http/https, convert ws/wss for validation
97+
String urlForValidation =
98+
url.replaceFirst("^ws://", "http://").replaceFirst("^wss://", "https://");
99+
HttpUrl parsedUrl = HttpUrl.parse(urlForValidation);
100+
if (parsedUrl == null) {
101+
throw new ApiException(
102+
Status.builder()
103+
.statusCode(PublicErrorDef.INVALID_URL.getStatusCode())
104+
.code(PublicErrorDef.INVALID_URL.getErrorCode())
105+
.message(
106+
StringUtils.format(
107+
"%s [detail=%s]", PublicErrorDef.INVALID_URL.getErrorMsg(), url))
108+
.build());
109+
}
81110
Request request = bd.url(url).build();
82111
return request;
83112
}

src/main/java/com/alibaba/dashscope/audio/qwen_tts_realtime/QwenTtsRealtime.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33

44
import static com.alibaba.dashscope.utils.JsonUtils.gson;
55

6+
import com.alibaba.dashscope.common.PublicErrorDef;
7+
import com.alibaba.dashscope.common.Status;
8+
import com.alibaba.dashscope.exception.ApiException;
69
import com.alibaba.dashscope.exception.NoApiKeyException;
710
import com.alibaba.dashscope.protocol.DashScopeHeaders;
811
import com.alibaba.dashscope.protocol.okhttp.OkHttpClientFactory;
912
import com.alibaba.dashscope.utils.ApiKey;
1013
import com.alibaba.dashscope.utils.Constants;
1114
import com.alibaba.dashscope.utils.JsonUtils;
15+
import com.alibaba.dashscope.utils.StringUtils;
1216
import com.google.gson.JsonObject;
1317
import java.util.HashMap;
1418
import java.util.Map;
@@ -226,6 +230,31 @@ private Request buildConnectionRequest(
226230
if (baseWebSocketUrl != null) {
227231
url = baseWebSocketUrl;
228232
}
233+
// Validate URL before building request to provide clear error message
234+
if (url == null || url.isEmpty()) {
235+
throw new ApiException(
236+
Status.builder()
237+
.statusCode(PublicErrorDef.INVALID_URL.getStatusCode())
238+
.code(PublicErrorDef.INVALID_URL.getErrorCode())
239+
.message(
240+
StringUtils.format(
241+
"%s [detail=URL is null or empty]", PublicErrorDef.INVALID_URL.getErrorMsg()))
242+
.build());
243+
}
244+
// HttpUrl.parse() only supports http/https, convert ws/wss for validation
245+
String urlForValidation =
246+
url.replaceFirst("^ws://", "http://").replaceFirst("^wss://", "https://");
247+
HttpUrl parsedUrl = HttpUrl.parse(urlForValidation);
248+
if (parsedUrl == null) {
249+
throw new ApiException(
250+
Status.builder()
251+
.statusCode(PublicErrorDef.INVALID_URL.getStatusCode())
252+
.code(PublicErrorDef.INVALID_URL.getErrorCode())
253+
.message(
254+
StringUtils.format(
255+
"%s [detail=%s]", PublicErrorDef.INVALID_URL.getErrorMsg(), url))
256+
.build());
257+
}
229258
Request request = bd.url(url).build();
230259
return request;
231260
}

src/main/java/com/alibaba/dashscope/common/DashScopeResult.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ private Map<String, Object> changeHeaders(Map<String, List<String>> headers) {
310310
static {
311311
LEGACY_ERROR_KEYWORDS.put("InvalidParameter", 400);
312312
LEGACY_ERROR_KEYWORDS.put("BadRequest", 400);
313+
LEGACY_ERROR_KEYWORDS.put("DataInspection", 400);
314+
LEGACY_ERROR_KEYWORDS.put("Inspection", 400);
313315
LEGACY_ERROR_KEYWORDS.put("Unauthorized", 401);
314316
LEGACY_ERROR_KEYWORDS.put("ApiKey", 401);
315317
LEGACY_ERROR_KEYWORDS.put("Forbidden", 403);
@@ -353,8 +355,8 @@ private int resolveStatusCode(Integer bodyStatusCode, Integer httpStatusCode, St
353355
}
354356
}
355357
}
356-
return bodyStatusCode != null
358+
return bodyStatusCode != null && bodyStatusCode != 200
357359
? bodyStatusCode
358-
: (httpStatusCode != null ? httpStatusCode : 200);
360+
: (httpStatusCode != null && httpStatusCode != 200 ? httpStatusCode : 400);
359361
}
360362
}

0 commit comments

Comments
 (0)