SHA256
27 03 25
Доделал API функции для авторификации и работы с сессиями сервер и документ для разработчиков по Авторификациии и серверам Всё работает
This commit is contained in:
+36
-5
@@ -185,7 +185,10 @@ public final class JsonInboundProcessor {
|
||||
requestId,
|
||||
WireCodes.Status.BAD_REQUEST,
|
||||
"BAD_REQUEST_FORMAT",
|
||||
"Некорректный формат запроса: не удалось распарсить поля payload"
|
||||
NetExceptionResponseFactory.detailedMessage(
|
||||
"Некорректный формат запроса: не удалось распарсить поля payload",
|
||||
mapErr
|
||||
)
|
||||
);
|
||||
|
||||
String out = writeResponse(err);
|
||||
@@ -216,7 +219,10 @@ public final class JsonInboundProcessor {
|
||||
requestId,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_HANDLER_ERROR",
|
||||
"Неожиданная ошибка при обработке операции: " + op
|
||||
NetExceptionResponseFactory.detailedMessage(
|
||||
"Неожиданная ошибка при обработке операции: " + op,
|
||||
handlerError
|
||||
)
|
||||
);
|
||||
|
||||
String out = writeResponse(err);
|
||||
@@ -254,7 +260,7 @@ public final class JsonInboundProcessor {
|
||||
requestId,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера", e)
|
||||
);
|
||||
|
||||
String out = writeResponse(err);
|
||||
@@ -281,6 +287,7 @@ public final class JsonInboundProcessor {
|
||||
* "op": ...,
|
||||
* "requestId": ...,
|
||||
* "status": ...,
|
||||
* "ok": true|false,
|
||||
* "payload": { ... }
|
||||
* }
|
||||
*/
|
||||
@@ -293,18 +300,39 @@ public final class JsonInboundProcessor {
|
||||
String op = full.hasNonNull("op") ? full.get("op").asText() : null;
|
||||
String requestId = full.hasNonNull("requestId") ? full.get("requestId").asText() : null;
|
||||
int status = full.hasNonNull("status") ? full.get("status").asInt() : 0;
|
||||
boolean ok = status >= 200 && status < 300;
|
||||
|
||||
String error = null;
|
||||
if (!ok) {
|
||||
if (full.hasNonNull("error")) error = full.get("error").asText();
|
||||
else if (full.hasNonNull("code")) error = full.get("code").asText();
|
||||
}
|
||||
|
||||
String message = null;
|
||||
if (!ok && full.hasNonNull("message")) {
|
||||
message = full.get("message").asText();
|
||||
}
|
||||
|
||||
// Удаляем базовые поля и payload из "полного" объекта,
|
||||
// всё остальное отправляем внутрь payload.
|
||||
full.remove("op");
|
||||
full.remove("requestId");
|
||||
full.remove("status");
|
||||
full.remove("ok");
|
||||
full.remove("error");
|
||||
full.remove("code");
|
||||
if (!ok) full.remove("message");
|
||||
full.remove("payload");
|
||||
|
||||
ObjectNode root = JSON_MAPPER.createObjectNode();
|
||||
if (op != null) root.put("op", op); else root.putNull("op");
|
||||
if (requestId != null) root.put("requestId", requestId); else root.putNull("requestId");
|
||||
root.put("status", status);
|
||||
root.put("ok", ok);
|
||||
if (!ok) {
|
||||
if (error != null) root.put("error", error); else root.putNull("error");
|
||||
if (message != null) root.put("message", message); else root.putNull("message");
|
||||
}
|
||||
|
||||
// payload — это всё, что осталось от full (может быть пустым объектом {})
|
||||
root.set("payload", full);
|
||||
@@ -321,7 +349,10 @@ public final class JsonInboundProcessor {
|
||||
return "{\"op\":\"" + safe(response != null ? response.getOp() : null) +
|
||||
"\",\"requestId\":\"" + safe(response != null ? response.getRequestId() : null) +
|
||||
"\",\"status\":" + (response != null ? response.getStatus() : 500) +
|
||||
",\"payload\":{\"code\":\"SERIALIZATION_ERROR\",\"message\":\"Ошибка сериализации ответа\"}}";
|
||||
",\"ok\":false" +
|
||||
",\"error\":\"SERIALIZATION_ERROR\"" +
|
||||
",\"message\":\"Ошибка сериализации ответа\"" +
|
||||
",\"payload\":{}}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,4 +376,4 @@ public final class JsonInboundProcessor {
|
||||
return String.valueOf(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -3,11 +3,8 @@ package server.logic.ws_protocol.JSON.entyties;
|
||||
/**
|
||||
* Ответ с ошибкой (любой отказ).
|
||||
*.
|
||||
* В payload будет:
|
||||
* {
|
||||
* "code": "...",
|
||||
* "message": "..."
|
||||
* }
|
||||
* В wire-формате error/message поднимаются на верхний уровень,
|
||||
* а payload остаётся объектом.
|
||||
*/
|
||||
public class Net_Exception_Response extends Net_Response {
|
||||
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@ package server.logic.ws_protocol.JSON.entyties;
|
||||
* "op": "...",
|
||||
* "requestId": "...",
|
||||
* "status": 200,
|
||||
* "ok": true,
|
||||
* "payload": { ... } // и для успеха, и для ошибки
|
||||
* }
|
||||
*/
|
||||
@@ -29,6 +30,6 @@ public abstract class Net_Response extends Net_Request {
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return status == 200;
|
||||
return status >= 200 && status < 300;
|
||||
}
|
||||
}
|
||||
|
||||
+34
-21
@@ -49,6 +49,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Net_CreateAuthSession__Handler.class);
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
private static final long CLOSE_AFTER_ERROR_DELAY_MS = 75L;
|
||||
|
||||
public static final long ALLOWED_SKEW_MS = 30_000L;
|
||||
|
||||
@@ -68,7 +69,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"NO_STEP1_CONTEXT",
|
||||
"Шаг 1 авторизации не был корректно выполнен для данного соединения"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: no step1 context or bad auth state");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: no step1 context or bad auth state");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"EMPTY_LOGIN",
|
||||
"Пустой login"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: empty login");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: empty login");
|
||||
return err;
|
||||
}
|
||||
if (!login.equals(loginFromContext)) {
|
||||
@@ -92,7 +93,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"LOGIN_MISMATCH",
|
||||
"login не соответствует контексту AuthChallenge"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: login mismatch");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: login mismatch");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -106,7 +107,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"DB_ERROR_USER_LOOKUP",
|
||||
"Ошибка БД при получении пользователя"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: db user lookup");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: db user lookup");
|
||||
return err;
|
||||
}
|
||||
if (user == null) {
|
||||
@@ -116,7 +117,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"USER_NOT_FOUND",
|
||||
"Пользователь не найден"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: user not found");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: user not found");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"NO_LOGIN",
|
||||
"Для пользователя не задан login в БД"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: no login");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: no login");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -139,7 +140,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"EMPTY_STORAGE_PWD",
|
||||
"Пустой storagePwd"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: empty storagePwd");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: empty storagePwd");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"EMPTY_SESSION_KEY",
|
||||
"Пустой sessionKey"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: empty session key");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: empty session key");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -165,7 +166,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"UNSUPPORTED_KEY_ALGORITHM",
|
||||
"sessionKey prefix is not supported"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: unsupported session key algorithm");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: unsupported session key algorithm");
|
||||
return err;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Net_Response err = NetExceptionResponseFactory.error(
|
||||
@@ -174,7 +175,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"BAD_BASE64",
|
||||
"Некорректный формат sessionKey"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: bad session key format");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: bad session key format");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -186,7 +187,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"EMPTY_SIGNATURE",
|
||||
"Пустая цифровая подпись"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: empty signature");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: empty signature");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -200,7 +201,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"TIME_SKEW",
|
||||
"Время клиента отличается от сервера более чем на 30 секунд"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: time skew");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: time skew");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -217,7 +218,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"NO_DEVICE_KEY",
|
||||
"Отсутствует deviceKey у пользователя"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: no deviceKey");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: no deviceKey");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -230,7 +231,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"EMPTY_AUTH_NONCE",
|
||||
"Пустой authNonce"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: empty authNonce");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: empty authNonce");
|
||||
return err;
|
||||
}
|
||||
if (!authNonce.equals(authNonceFromReq)) {
|
||||
@@ -240,7 +241,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"AUTH_NONCE_MISMATCH",
|
||||
"authNonce не соответствует контексту AuthChallenge"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: authNonce mismatch");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: authNonce mismatch");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -252,7 +253,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"EMPTY_DEVICE_KEY",
|
||||
"Пустой deviceKey"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: empty deviceKey");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: empty deviceKey");
|
||||
return err;
|
||||
}
|
||||
deviceKeyFromReq = deviceKeyFromReq.trim();
|
||||
@@ -265,7 +266,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"DEVICE_KEY_NOT_ACTUAL",
|
||||
"device_key не соответствует актуальной версии"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: device key mismatch");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: device key mismatch");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -287,7 +288,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"UNSUPPORTED_KEY_ALGORITHM",
|
||||
"deviceKey algorithm is not supported"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: unsupported device key algorithm");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: unsupported device key algorithm");
|
||||
return err;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Net_Response err = NetExceptionResponseFactory.error(
|
||||
@@ -296,7 +297,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"BAD_BASE64",
|
||||
"Некорректный формат Base64 для ключа или подписи"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: bad base64");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: bad base64");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -307,7 +308,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"BAD_SIGNATURE",
|
||||
"Подпись не прошла проверку"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: bad signature");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: bad signature");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -364,7 +365,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
"DB_ERROR_SESSION_CREATE",
|
||||
"Ошибка БД при создании сессии"
|
||||
);
|
||||
WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: db error");
|
||||
closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: db error");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -414,4 +415,16 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
RANDOM.nextBytes(buf);
|
||||
return Base64Ws.encode(buf);
|
||||
}
|
||||
|
||||
private static void closeConnectionAfterErrorResponse(ConnectionContext ctx, int statusCode, String reason) {
|
||||
if (ctx == null) return;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(CLOSE_AFTER_ERROR_DELAY_MS);
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
WsConnectionUtils.closeConnection(ctx, statusCode, reason);
|
||||
}, "CreateAuthSessionClose-" + System.identityHashCode(ctx)).start();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -66,7 +66,7 @@ public class Net_ListSessions_Handler implements JsonMessageHandler {
|
||||
info.setSessionId(s.getSessionId());
|
||||
info.setClientInfoFromClient(s.getClientInfoFromClient());
|
||||
info.setClientInfoFromRequest(s.getClientInfoFromRequest());
|
||||
info.setLastAuthirificatedAtMs(s.getLastAuthirificatedAtMs());
|
||||
info.setLastAuthenticatedAtMs(s.getLastAuthirificatedAtMs());
|
||||
|
||||
String ip = s.getClientIp();
|
||||
String geo = GeoLookupService.resolveCountryCityOrIpWithCache(ip);
|
||||
@@ -83,4 +83,4 @@ public class Net_ListSessions_Handler implements JsonMessageHandler {
|
||||
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -17,7 +17,7 @@ import java.util.List;
|
||||
* "clientInfoFromClient": "...",
|
||||
* "clientInfoFromRequest": "...",
|
||||
* "geo": "Country, City" | "unknown",
|
||||
* "lastAuthirificatedAtMs": 1733310000000
|
||||
* "lastAuthenticatedAtMs": 1733310000000
|
||||
* },
|
||||
* ...
|
||||
* ]
|
||||
@@ -56,7 +56,7 @@ public class Net_ListSessions_Response extends Net_Response {
|
||||
private String geo;
|
||||
|
||||
/** Время последней успешной авторизации/refresh (мс с 1970-01-01). */
|
||||
private long lastAuthirificatedAtMs;
|
||||
private long lastAuthenticatedAtMs;
|
||||
|
||||
// --- getters / setters ---
|
||||
|
||||
@@ -92,12 +92,12 @@ public class Net_ListSessions_Response extends Net_Response {
|
||||
this.geo = geo;
|
||||
}
|
||||
|
||||
public long getLastAuthirificatedAtMs() {
|
||||
return lastAuthirificatedAtMs;
|
||||
public long getLastAuthenticatedAtMs() {
|
||||
return lastAuthenticatedAtMs;
|
||||
}
|
||||
|
||||
public void setLastAuthirificatedAtMs(long lastAuthirificatedAtMs) {
|
||||
this.lastAuthirificatedAtMs = lastAuthirificatedAtMs;
|
||||
public void setLastAuthenticatedAtMs(long lastAuthenticatedAtMs) {
|
||||
this.lastAuthenticatedAtMs = lastAuthenticatedAtMs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -91,7 +91,7 @@ public class Net_GetFriendsLists_Handler implements JsonMessageHandler {
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при GetFriendsLists", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -111,4 +111,4 @@ public class Net_GetFriendsLists_Handler implements JsonMessageHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -178,8 +178,8 @@ public class Net_AddUser_Handler implements JsonMessageHandler {
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при AddUser", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -77,8 +77,8 @@ public class Net_GetUser_Handler implements JsonMessageHandler {
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при GetUser", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -70,8 +70,8 @@ public class Net_SearchUsers_Handler implements JsonMessageHandler {
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при SearchUsers", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -83,8 +83,8 @@ public class Net_GetUserParam_Handler implements JsonMessageHandler {
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при GetUserParam", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -84,8 +84,8 @@ public class Net_ListUserParams_Handler implements JsonMessageHandler {
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при ListUserParams", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -181,8 +181,8 @@ public class Net_UpsertUserParam_Handler implements JsonMessageHandler {
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
"Внутренняя ошибка сервера"
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при UpsertUserParam", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
-1
@@ -9,6 +9,8 @@ import server.logic.ws_protocol.JSON.entyties.Net_Request;
|
||||
*/
|
||||
public final class NetExceptionResponseFactory {
|
||||
|
||||
private static final int MAX_DETAIL_LEN = 240;
|
||||
|
||||
private NetExceptionResponseFactory() {
|
||||
// запрет на создание объектов
|
||||
}
|
||||
@@ -35,6 +37,39 @@ public final class NetExceptionResponseFactory {
|
||||
return resp;
|
||||
}
|
||||
|
||||
public static String detailedMessage(String prefix, Throwable error) {
|
||||
String safePrefix = prefix == null || prefix.isBlank()
|
||||
? "Внутренняя ошибка сервера"
|
||||
: prefix.trim();
|
||||
|
||||
if (error == null) {
|
||||
return safePrefix;
|
||||
}
|
||||
|
||||
String className = error.getClass().getSimpleName();
|
||||
if (className == null || className.isBlank()) {
|
||||
className = error.getClass().getName();
|
||||
}
|
||||
|
||||
String detail = error.getMessage();
|
||||
StringBuilder sb = new StringBuilder(safePrefix)
|
||||
.append(": ")
|
||||
.append(className);
|
||||
|
||||
if (detail != null && !detail.isBlank()) {
|
||||
sb.append(": ").append(detail.trim());
|
||||
}
|
||||
|
||||
String message = sb.toString()
|
||||
.replace('\n', ' ')
|
||||
.replace('\r', ' ');
|
||||
|
||||
if (message.length() <= MAX_DETAIL_LEN) {
|
||||
return message;
|
||||
}
|
||||
return message.substring(0, MAX_DETAIL_LEN - 3) + "...";
|
||||
}
|
||||
|
||||
/**
|
||||
* Вариант для случаев, когда NetRequest ещё не распарсен,
|
||||
* но мы уже знаем op и requestId (или они null).
|
||||
@@ -53,4 +88,4 @@ public final class NetExceptionResponseFactory {
|
||||
resp.setMessage(message);
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user