Add registration failure diagnostics
This commit is contained in:
parent
b057119fd3
commit
7d1909858e
@ -0,0 +1,117 @@
|
|||||||
|
package com.red.circle.framework.feign.decoder;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.red.circle.framework.core.exception.ResponseException;
|
||||||
|
import com.red.circle.framework.core.request.ResponseHeaderConstant;
|
||||||
|
import com.red.circle.framework.core.response.ResponseErrorCode;
|
||||||
|
import com.red.circle.framework.core.spring.ApplicationContextUtils;
|
||||||
|
import com.red.circle.framework.dto.ResultResponse;
|
||||||
|
import com.red.circle.tool.core.http.HttpConstant;
|
||||||
|
import com.red.circle.tool.core.json.JacksonUtils;
|
||||||
|
import com.red.circle.tool.core.text.StringUtils;
|
||||||
|
import feign.Request;
|
||||||
|
import feign.Response;
|
||||||
|
import feign.codec.ErrorDecoder;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class FeignErrorDecoder implements ErrorDecoder {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(FeignErrorDecoder.class);
|
||||||
|
|
||||||
|
private static final List<Integer> PROCESS_RESULT_RESPONSE = List.of(
|
||||||
|
ResponseErrorCode.NOT_ACCEPTABLE.getCode(),
|
||||||
|
ResponseErrorCode.REQUEST_PARAMETER_ERROR.getCode()
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Exception decode(String methodKey, Response response) {
|
||||||
|
if (PROCESS_RESULT_RESPONSE.stream()
|
||||||
|
.anyMatch(code -> Objects.equals(response.status(), code))) {
|
||||||
|
ResponseException exception = parseResponseException(methodKey, response);
|
||||||
|
if (Objects.nonNull(exception)) {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HttpConstant.is4xx(response.status())) {
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ResponseHeaderConstant.existsHeaderValue(response.headers(), "RC-No-Retry", "true")) {
|
||||||
|
ResponseException exception = parseResponseException(methodKey, response);
|
||||||
|
if (Objects.nonNull(exception)) {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String reqMapping(Response response) {
|
||||||
|
Request request = response.request();
|
||||||
|
if (Objects.isNull(request)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return request.httpMethod() + " " + request.url();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseException createResponseException(String methodKey, Response response) {
|
||||||
|
String errorCodeName = Objects.equals(response.status(), 429)
|
||||||
|
? "REQ_LIMIT_INNER_DECODER"
|
||||||
|
: "ERROR_INNER_DECODER";
|
||||||
|
return new ResponseException(response.status(), errorCodeName, getErrorMsg(methodKey, response));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getErrorMsg(String methodKey, Response response) {
|
||||||
|
return StringUtils.isBlankOrElse(response.reason(), "") + reqMapping(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseException parseResponseException(String methodKey, Response response) {
|
||||||
|
ResultResponse<Void> responseBody = parseResponse(response);
|
||||||
|
if (Objects.nonNull(responseBody)) {
|
||||||
|
Map<String, Object> extValues = Optional.ofNullable(responseBody.getExtValues())
|
||||||
|
.orElseGet(HashMap::new);
|
||||||
|
|
||||||
|
extValues.put("innerError",
|
||||||
|
"[" + methodKey + "]" + StringUtils.isBlankOrElse(response.reason(), ""));
|
||||||
|
|
||||||
|
return new ResponseException(
|
||||||
|
responseBody.getErrorCode(),
|
||||||
|
responseBody.getErrorCodeName(),
|
||||||
|
responseBody.getErrorMsg(),
|
||||||
|
extValues
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultResponse<Void> parseResponse(Response response) {
|
||||||
|
if (Objects.isNull(response.body())) {
|
||||||
|
log.warn("Feign error response body is null, status={}, reason={}, request={}",
|
||||||
|
response.status(), response.reason(), reqMapping(response));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStream inputStream = response.body().asInputStream()) {
|
||||||
|
String responseCompression = ApplicationContextUtils.getApplicationContext()
|
||||||
|
.getEnvironment()
|
||||||
|
.getProperty("spring.cloud.openfeign.compression.response.enabled");
|
||||||
|
return JacksonUtils.readValue(inputStream, new TypeReference<>() {
|
||||||
|
}, Objects.equals(responseCompression, "true"));
|
||||||
|
} catch (IOException | RuntimeException ex) {
|
||||||
|
log.warn("Parse feign error response body failed, status={}, reason={}, request={}",
|
||||||
|
response.status(), response.reason(), reqMapping(response), ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,6 +14,7 @@ import com.red.circle.other.inner.model.cmd.user.UserProfileCmd;
|
|||||||
import com.red.circle.other.inner.model.cmd.user.account.CreateAccountCmd;
|
import com.red.circle.other.inner.model.cmd.user.account.CreateAccountCmd;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,6 +24,7 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class CheckRegisterUserProfileProcess {
|
public class CheckRegisterUserProfileProcess {
|
||||||
|
|
||||||
private final OssServiceClient ossServiceClient;
|
private final OssServiceClient ossServiceClient;
|
||||||
@ -32,7 +34,7 @@ public class CheckRegisterUserProfileProcess {
|
|||||||
UserProfileCmd profileCmd = cmd.getProfile();
|
UserProfileCmd profileCmd = cmd.getProfile();
|
||||||
setUserCountryInfo(profileCmd);
|
setUserCountryInfo(profileCmd);
|
||||||
calculationAge(profileCmd);
|
calculationAge(profileCmd);
|
||||||
completeAvatarUrl(profileCmd);
|
completeAvatarUrl(cmd, profileCmd);
|
||||||
checkGenerateDefaultNickname(profileCmd);
|
checkGenerateDefaultNickname(profileCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,12 +48,27 @@ public class CheckRegisterUserProfileProcess {
|
|||||||
cmd.setUserNickname(KeywordConstant.filter(cmd.getUserNickname()));
|
cmd.setUserNickname(KeywordConstant.filter(cmd.getUserNickname()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void completeAvatarUrl(UserProfileCmd cmd) {
|
private void completeAvatarUrl(CreateAccountCmd accountCmd, UserProfileCmd cmd) {
|
||||||
if (StringUtils.isNotBlank(cmd.getUserAvatar())) {
|
if (StringUtils.isNotBlank(cmd.getUserAvatar())) {
|
||||||
cmd.setUserAvatar(ResponseAssert.requiredSuccess(
|
String sourceAvatar = cmd.getUserAvatar();
|
||||||
ossServiceClient.processImgSaveAsCompressZoom(cmd.getUserAvatar(),
|
log.info(
|
||||||
ImageSizeConst.COVER_HEIGHT)
|
"Register avatar process start, userId={}, type={}, openId={}, nickname={}, countryCode={}, source={}",
|
||||||
));
|
accountCmd.getReqUserId(), accountCmd.getType(), accountCmd.getOpenId(),
|
||||||
|
cmd.getUserNickname(), cmd.getCountryCode(), sourceAvatar);
|
||||||
|
try {
|
||||||
|
String processedAvatar = ResponseAssert.requiredSuccess(
|
||||||
|
ossServiceClient.processImgSaveAsCompressZoom(sourceAvatar, ImageSizeConst.COVER_HEIGHT)
|
||||||
|
);
|
||||||
|
cmd.setUserAvatar(processedAvatar);
|
||||||
|
log.info("Register avatar process success, userId={}, source={}, target={}",
|
||||||
|
accountCmd.getReqUserId(), sourceAvatar, processedAvatar);
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
log.error(
|
||||||
|
"Register avatar process failed, userId={}, type={}, openId={}, nickname={}, countryCode={}, source={}",
|
||||||
|
accountCmd.getReqUserId(), accountCmd.getType(), accountCmd.getOpenId(),
|
||||||
|
cmd.getUserNickname(), cmd.getCountryCode(), sourceAvatar, ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -155,7 +155,15 @@ public class UserAccountCommon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String requestUserSign(Long userId) {
|
private String requestUserSign(Long userId) {
|
||||||
return ResponseAssert.requiredSuccess(imAccountClient.createUserSig(userId));
|
log.info("Register userSig create start, userId={}", userId);
|
||||||
|
try {
|
||||||
|
String userSig = ResponseAssert.requiredSuccess(imAccountClient.createUserSig(userId));
|
||||||
|
log.info("Register userSig create success, userId={}", userId);
|
||||||
|
return userSig;
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
log.error("Register userSig create failed, userId={}", userId, ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseInfo toBaseInfo(CreateAccountCmd cmd) {
|
private BaseInfo toBaseInfo(CreateAccountCmd cmd) {
|
||||||
|
|||||||
@ -0,0 +1,117 @@
|
|||||||
|
package com.red.circle.framework.feign.decoder;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.red.circle.framework.core.exception.ResponseException;
|
||||||
|
import com.red.circle.framework.core.request.ResponseHeaderConstant;
|
||||||
|
import com.red.circle.framework.core.response.ResponseErrorCode;
|
||||||
|
import com.red.circle.framework.core.spring.ApplicationContextUtils;
|
||||||
|
import com.red.circle.framework.dto.ResultResponse;
|
||||||
|
import com.red.circle.tool.core.http.HttpConstant;
|
||||||
|
import com.red.circle.tool.core.json.JacksonUtils;
|
||||||
|
import com.red.circle.tool.core.text.StringUtils;
|
||||||
|
import feign.Request;
|
||||||
|
import feign.Response;
|
||||||
|
import feign.codec.ErrorDecoder;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class FeignErrorDecoder implements ErrorDecoder {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(FeignErrorDecoder.class);
|
||||||
|
|
||||||
|
private static final List<Integer> PROCESS_RESULT_RESPONSE = List.of(
|
||||||
|
ResponseErrorCode.NOT_ACCEPTABLE.getCode(),
|
||||||
|
ResponseErrorCode.REQUEST_PARAMETER_ERROR.getCode()
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Exception decode(String methodKey, Response response) {
|
||||||
|
if (PROCESS_RESULT_RESPONSE.stream()
|
||||||
|
.anyMatch(code -> Objects.equals(response.status(), code))) {
|
||||||
|
ResponseException exception = parseResponseException(methodKey, response);
|
||||||
|
if (Objects.nonNull(exception)) {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HttpConstant.is4xx(response.status())) {
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ResponseHeaderConstant.existsHeaderValue(response.headers(), "RC-No-Retry", "true")) {
|
||||||
|
ResponseException exception = parseResponseException(methodKey, response);
|
||||||
|
if (Objects.nonNull(exception)) {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createResponseException(methodKey, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String reqMapping(Response response) {
|
||||||
|
Request request = response.request();
|
||||||
|
if (Objects.isNull(request)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return request.httpMethod() + " " + request.url();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseException createResponseException(String methodKey, Response response) {
|
||||||
|
String errorCodeName = Objects.equals(response.status(), 429)
|
||||||
|
? "REQ_LIMIT_INNER_DECODER"
|
||||||
|
: "ERROR_INNER_DECODER";
|
||||||
|
return new ResponseException(response.status(), errorCodeName, getErrorMsg(methodKey, response));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getErrorMsg(String methodKey, Response response) {
|
||||||
|
return StringUtils.isBlankOrElse(response.reason(), "") + reqMapping(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseException parseResponseException(String methodKey, Response response) {
|
||||||
|
ResultResponse<Void> responseBody = parseResponse(response);
|
||||||
|
if (Objects.nonNull(responseBody)) {
|
||||||
|
Map<String, Object> extValues = Optional.ofNullable(responseBody.getExtValues())
|
||||||
|
.orElseGet(HashMap::new);
|
||||||
|
|
||||||
|
extValues.put("innerError",
|
||||||
|
"[" + methodKey + "]" + StringUtils.isBlankOrElse(response.reason(), ""));
|
||||||
|
|
||||||
|
return new ResponseException(
|
||||||
|
responseBody.getErrorCode(),
|
||||||
|
responseBody.getErrorCodeName(),
|
||||||
|
responseBody.getErrorMsg(),
|
||||||
|
extValues
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultResponse<Void> parseResponse(Response response) {
|
||||||
|
if (Objects.isNull(response.body())) {
|
||||||
|
log.warn("Feign error response body is null, status={}, reason={}, request={}",
|
||||||
|
response.status(), response.reason(), reqMapping(response));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStream inputStream = response.body().asInputStream()) {
|
||||||
|
String responseCompression = ApplicationContextUtils.getApplicationContext()
|
||||||
|
.getEnvironment()
|
||||||
|
.getProperty("spring.cloud.openfeign.compression.response.enabled");
|
||||||
|
return JacksonUtils.readValue(inputStream, new TypeReference<>() {
|
||||||
|
}, Objects.equals(responseCompression, "true"));
|
||||||
|
} catch (IOException | RuntimeException ex) {
|
||||||
|
log.warn("Parse feign error response body failed, status={}, reason={}, request={}",
|
||||||
|
response.status(), response.reason(), reqMapping(response), ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user