Skip to content

Commit 5f40c49

Browse files
authored
Merge pull request #1224 from gooddata/dp-fix-close
fix: mitigate StreamClosedException
2 parents 49e5208 + 4e89fdc commit 5f40c49

File tree

8 files changed

+1487
-100
lines changed

8 files changed

+1487
-100
lines changed

gooddata-java/src/main/java/com/gooddata/sdk/common/HttpClient5ComponentsClientHttpRequestFactory.java

Lines changed: 111 additions & 91 deletions
Large diffs are not rendered by default.

gooddata-java/src/main/java/com/gooddata/sdk/service/account/AccountService.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import com.gooddata.sdk.model.gdc.UriResponse;
1414
import com.gooddata.sdk.service.AbstractService;
1515
import com.gooddata.sdk.service.GoodDataSettings;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
1618
import org.springframework.http.HttpStatus;
1719
import org.springframework.http.converter.json.MappingJacksonValue;
1820
import org.springframework.web.client.RestClientException;
@@ -28,6 +30,8 @@
2830
*/
2931
public class AccountService extends AbstractService {
3032

33+
private static final Logger logger = LoggerFactory.getLogger(AccountService.class);
34+
3135
public static final UriTemplate ACCOUNT_TEMPLATE = new UriTemplate(Account.URI);
3236
public static final UriTemplate ACCOUNTS_TEMPLATE = new UriTemplate(Account.ACCOUNTS_URI);
3337
public static final UriTemplate ACCOUNT_BY_LOGIN_TEMPLATE = new UriTemplate(Account.ACCOUNT_BY_EMAIL_URI);
@@ -63,11 +67,47 @@ public void logout() {
6367
try {
6468
final String id = getCurrent().getId();
6569
restTemplate.delete(Account.LOGIN_URI, id);
70+
} catch (GoodDataRestException e) {
71+
if (isAlreadyLoggedOutError(e)) {
72+
logger.debug("User already logged out (status={}, errorCode={}, message={})",
73+
e.getStatusCode(), e.getErrorCode(), e.getMessage());
74+
return;
75+
}
76+
throw new GoodDataException("Unable to logout", e);
6677
} catch (GoodDataException | RestClientException e) {
6778
throw new GoodDataException("Unable to logout", e);
6879
}
6980
}
7081

82+
/**
83+
* Checks if the exception indicates the user is already logged out.
84+
* This is not an error condition - it means the logout goal is already achieved.
85+
*/
86+
private static boolean isAlreadyLoggedOutError(final GoodDataRestException e) {
87+
// HTTP 400 indicates a client error, which includes "not logged in"
88+
if (e.getStatusCode() != HttpStatus.BAD_REQUEST.value()) {
89+
return false;
90+
}
91+
92+
// Prefer error code matching (API contract) over message content (locale-sensitive)
93+
final String errorCode = e.getErrorCode();
94+
if (errorCode != null && !errorCode.isEmpty()) {
95+
// Match known error codes for "not logged in" state
96+
// Common patterns: gdc.login.not_logged_in, NOT_LOGGED_IN, etc.
97+
final String lowerErrorCode = errorCode.toLowerCase();
98+
return lowerErrorCode.contains("not_logged") || lowerErrorCode.contains("notlogged");
99+
}
100+
101+
// Fallback to message matching if error code is not available
102+
final String message = e.getMessage();
103+
if (message != null) {
104+
final String lowerMessage = message.toLowerCase();
105+
return lowerMessage.contains("not logged in") || lowerMessage.contains("not logged-in");
106+
}
107+
108+
return false;
109+
}
110+
71111
/**
72112
* Creates new account in given organization (domain).
73113
* Only domain admin is allowed create new accounts! This means rest request has to authorized as domain admin.

0 commit comments

Comments
 (0)