-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Description
Problem
When the GigaChat auth endpoint (ngw.devices.sberbank.ru) returns an error with Content-Type: text/html (e.g., 502/503 gateway error page), GigaChatOAuthClient.requestToken() produces an unhelpful exception:
Could not extract response: no suitable HttpMessageConverter found for response type
[class chat.giga.springai.api.auth.bearer.GigaChatOAuthClient$GigaChatAccessTokenResponse]
and content type [text/html]
The actual HTML body (which contains the real error — e.g., "502 Bad Gateway", maintenance message, WAF block) is never logged and is lost. This makes it very difficult to diagnose transient auth failures in production.
Root cause
In GigaChatOAuthClient.requestToken():
return this.restClient
.post()
.headers(headers -> buildAuthHeaders(headers, this.authToken))
.body("scope=" + this.scope)
.retrieve()
.onStatus(HttpStatusCode::isError, ((request, response) -> {
log.warn(
"Token request returned error status: {}, but attempting to parse response body",
response.getStatusCode());
// Allow parsing response body even on error status
}))
.body(GigaChatAccessTokenResponse.class);The onStatus handler:
- Logs only the HTTP status code (e.g., 502) — not the response body
- Swallows the error to attempt body parsing
- Body parsing then fails because
text/htmlhas no matchingHttpMessageConverterforGigaChatAccessTokenResponse - The original HTML content (which explains WHY the auth failed) is lost
Suggested fix
Read and log the full response body in the onStatus handler before attempting deserialization:
.onStatus(HttpStatusCode::isError, ((request, response) -> {
String body = new String(response.getBody().readAllBytes(), StandardCharsets.UTF_8);
String contentType = response.getHeaders().getContentType() != null
? response.getHeaders().getContentType().toString() : "unknown";
log.warn("Token request failed: status={}, contentType={}, body={}",
response.getStatusCode(), contentType, body);
// If response is not JSON, throw immediately with informative message
if (!contentType.contains("json")) {
throw new GigaChatAuthException(
"Auth endpoint returned non-JSON response (status=" + response.getStatusCode()
+ ", contentType=" + contentType + "): " + truncate(body, 500));
}
}))This way:
- The actual error page content is visible in logs (502 Bad Gateway, maintenance HTML, WAF block, etc.)
- Non-JSON responses fail fast with a clear message instead of the cryptic
HttpMessageConvertererror - JSON error responses still attempt parsing as before
Environment
spring-ai-gigachat:1.1.2- Spring Boot 3.5.11, Java 21
- Observed in production with parallel shadow calls to GigaChat API
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels