优化
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import feign.FeignException;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Set;
|
||||
|
||||
/** Explicit failure classification and bounded, credential-free delivery diagnostics. */
|
||||
public class EventDeliveryFailure extends IllegalStateException {
|
||||
private static final Set<String> PERMANENT_CODES = Set.of("A0401", "A0403", "EVT_PROTOCOL");
|
||||
private final boolean permanent;
|
||||
public EventDeliveryFailure(boolean permanent, String message) {
|
||||
super(message);
|
||||
this.permanent = permanent;
|
||||
}
|
||||
public static void requireSuccessful(ApiResponse<?> response) {
|
||||
requireSuccessful(response, Set.of());
|
||||
}
|
||||
public static void requireSuccessful(ApiResponse<?> response, Set<String> additionalPermanentCodes) {
|
||||
if (response == null) throw new EventDeliveryFailure(false, "Consumer returned an empty response");
|
||||
if (!response.successful()) {
|
||||
throw new EventDeliveryFailure(response.code() != null && (PERMANENT_CODES.contains(response.code()) || additionalPermanentCodes.contains(response.code())),
|
||||
"Consumer rejected event: code=" + response.code() + ", message=" + response.message()
|
||||
+ ", requestId=" + response.requestId() + ", traceId=" + response.traceId());
|
||||
}
|
||||
if (response.data() == null) throw new EventDeliveryFailure(false, "Consumer ACK is missing");
|
||||
}
|
||||
public static boolean isPermanent(Throwable failure) {
|
||||
Set<Throwable> seen = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
for (Throwable current = failure; current != null && seen.add(current); current = current.getCause()) {
|
||||
if (current instanceof EventDeliveryFailure delivery && delivery.permanent) return true;
|
||||
if (current instanceof FeignException http && (http.status() == 401 || http.status() == 403)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static String diagnostic(Throwable failure, String internalToken) {
|
||||
Throwable current = failure;
|
||||
Set<Throwable> seen = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
while (current.getCause() != null && seen.add(current)
|
||||
&& ("NoFallbackAvailableException".equals(current.getClass().getSimpleName())
|
||||
|| "No fallback available.".equals(current.getMessage()))) current = current.getCause();
|
||||
String message;
|
||||
if (current instanceof FeignException http) message = "HTTP " + http.status();
|
||||
else if (current instanceof JsonProcessingException) message = "Invalid event JSON";
|
||||
else message = current.getMessage() == null ? "unknown" : current.getMessage();
|
||||
String text = current.getClass().getSimpleName() + ": " + message;
|
||||
if (internalToken != null && !internalToken.isBlank()) text = text.replace(internalToken, "***");
|
||||
text = text.replaceAll("(?i)Bearer\\s+[^\\s,;\\\"']+", "Bearer ***")
|
||||
.replaceAll("(?i)((?:X-Internal-Service-Token|Authorization|access[_-]?token|refresh[_-]?token)\\s*[=:]\\s*)[^\\s,;]+", "$1***")
|
||||
.replaceAll("[\\r\\n\\t]+", " ");
|
||||
return text.length() > 500 ? text.substring(0, 500) : text;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user