Skip to content

Commit c04b4b4

Browse files
committed
modifying and correcting issues
1 parent c4b749e commit c04b4b4

File tree

3 files changed

+166
-113
lines changed

3 files changed

+166
-113
lines changed

core/src/main/java/google/registry/tools/RdapQueryCommand.java

Lines changed: 121 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.google.common.base.Splitter;
2323
import com.google.common.base.Strings;
2424
import com.google.common.collect.ImmutableMap;
25-
import com.google.common.flogger.GoogleLogger;
2625
import com.google.gson.JsonArray;
2726
import com.google.gson.JsonElement;
2827
import com.google.gson.JsonObject;
@@ -34,13 +33,12 @@
3433
import java.util.ArrayList;
3534
import java.util.List;
3635
import java.util.Map;
36+
import java.util.Optional;
3737

3838
/** Command to manually perform an RDAP query for any path. */
39-
@Parameters(separators = " =", commandDescription = "Manually perform an authenticated RDAP query")
39+
@Parameters(separators = " =", commandDescription = "Manually perform an RDAP query")
4040
public final class RdapQueryCommand implements CommandWithConnection {
4141

42-
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
43-
4442
@Parameter(
4543
description = "The ordered RDAP path segments that form the path (e.g., 'domain foo.dev').",
4644
required = true)
@@ -65,21 +63,10 @@ public void setConnection(ServiceConnection connection) {
6563

6664
@Override
6765
public void run() {
68-
checkArgument(!mainParameters.isEmpty(), "Missing RDAP path segments.");
6966

7067
String path = "/rdap/" + String.join("/", mainParameters);
7168

72-
ImmutableMap<String, String> queryParams =
73-
params.stream()
74-
.map(
75-
p -> {
76-
List<String> parts = Splitter.on('=').limit(2).splitToList(p);
77-
checkArgument(parts.size() == 2, "Invalid parameter format: %s", p);
78-
return parts;
79-
})
80-
.collect(toImmutableMap(parts -> parts.get(0), parts -> parts.get(1)));
81-
82-
logger.atInfo().log("Starting RDAP query for path: %s with params: %s", path, queryParams);
69+
ImmutableMap<String, String> queryParams = parseParams(params);
8370

8471
try {
8572
if (defaultConnection == null) {
@@ -94,92 +81,135 @@ public void run() {
9481
System.out.println(formatJsonElement(rdapJson, ""));
9582

9683
} catch (IOException e) {
97-
// Log the full exception for backend records, but without withCause(e) to
98-
// prevent automatic stack trace printing to the console.
99-
logger.atSevere().log("Request failed for path: %s: %s", path, e.getMessage());
100-
101-
String errorMessage = e.getMessage();
102-
String userFriendlyError;
103-
104-
if (errorMessage != null) {
105-
try {
106-
int jsonStartIndex = errorMessage.indexOf('{');
107-
if (jsonStartIndex != -1) {
108-
String jsonString = errorMessage.substring(jsonStartIndex);
109-
JsonElement errorJsonElement = JsonParser.parseString(jsonString);
110-
111-
if (errorJsonElement.isJsonObject()) {
112-
JsonObject errorObj = errorJsonElement.getAsJsonObject();
113-
String title = errorObj.has("title") ? errorObj.get("title").getAsString() : "Error";
114-
int errorCode = errorObj.has("errorCode") ? errorObj.get("errorCode").getAsInt() : -1;
115-
String description = "";
116-
if (errorObj.has("description")) {
117-
JsonElement descElement = errorObj.get("description");
118-
if (descElement.isJsonArray()) {
119-
StringBuilder sb = new StringBuilder();
120-
for (JsonElement element : descElement.getAsJsonArray()) {
121-
if (sb.length() > 0) sb.append("\n ");
122-
sb.append(element.getAsString());
123-
}
124-
description = sb.toString();
125-
} else if (descElement.isJsonPrimitive()) {
126-
description = descElement.getAsString();
127-
}
128-
}
129-
130-
StringBuilder improvedError = new StringBuilder();
131-
improvedError.append("RDAP Request Failed (Code ").append(errorCode).append("): ");
132-
improvedError.append(title);
133-
if (!Strings.isNullOrEmpty(description)) {
134-
improvedError.append("\n Description: ").append(description);
135-
}
136-
userFriendlyError = improvedError.toString();
137-
} else {
138-
userFriendlyError = "Request failed for " + path + ": " + errorMessage;
139-
}
140-
} else {
141-
// Fallback if no JSON, try to extract HTTP status from the message
142-
if (errorMessage.contains(": 501 Not Implemented")) {
143-
userFriendlyError =
144-
"RDAP Request Failed (Code 501): Not Implemented\n"
145-
+ " Description: The query for '"
146-
+ path
147-
+ "' was understood, but is not implemented by this registry.";
148-
} else if (errorMessage.contains(": 404 Not Found")) {
149-
userFriendlyError =
150-
"RDAP Request Failed (Code 404): Not Found\n"
151-
+ " Description: The resource at path '"
152-
+ path
153-
+ "' does not exist or no results matched the query.";
154-
} else {
155-
userFriendlyError =
156-
"Request failed for "
157-
+ path
158-
+ ": "
159-
+ errorMessage.substring(0, Math.min(errorMessage.length(), 150));
160-
}
161-
}
162-
} catch (Exception jsonEx) {
163-
logger.atWarning().withCause(jsonEx).log("Failed to parse error response as JSON, showing raw error.");
164-
userFriendlyError = "Request failed for " + path + ": " + errorMessage;
84+
handleIOException(path, e);
85+
}
86+
}
87+
88+
/** Parses the --params list into an ImmutableMap of query parameters. */
89+
private ImmutableMap<String, String> parseParams(List<String> paramsList) {
90+
return paramsList.stream()
91+
.map(
92+
p -> {
93+
List<String> parts = Splitter.on('=').limit(2).splitToList(p);
94+
checkArgument(parts.size() == 2, "Invalid parameter format: %s", p);
95+
return parts;
96+
})
97+
.collect(toImmutableMap(parts -> parts.get(0), parts -> parts.get(1)));
98+
}
99+
100+
/** Handles and formats IOException, printing a user-friendly message to System.err. */
101+
private void handleIOException(String path, IOException e) {
102+
103+
String errorMessage = e.getMessage();
104+
String userFriendlyError = formatUserFriendlyError(path, errorMessage);
105+
System.err.println(userFriendlyError);
106+
}
107+
108+
/** Formats a user-friendly error message from the IOException details. */
109+
private String formatUserFriendlyError(String path, String errorMessage) {
110+
if (errorMessage == null) {
111+
return "Request failed for " + path + ": No error message available.";
112+
}
113+
114+
Optional<JsonObject> errorJson = parseErrorJson(errorMessage);
115+
116+
if (errorJson.isPresent()) {
117+
return formatJsonError(errorJson.get());
118+
} else {
119+
return formatFallbackError(path, errorMessage);
120+
}
121+
}
122+
123+
/** Attempts to parse a JSON object from the IOException message. */
124+
private Optional<JsonObject> parseErrorJson(String errorMessage) {
125+
try {
126+
int jsonStartIndex = errorMessage.indexOf('{');
127+
if (jsonStartIndex != -1) {
128+
String jsonString = errorMessage.substring(jsonStartIndex);
129+
JsonElement errorJsonElement = JsonParser.parseString(jsonString);
130+
if (errorJsonElement.isJsonObject()) {
131+
return Optional.of(errorJsonElement.getAsJsonObject());
165132
}
166-
} else {
167-
userFriendlyError = "Request failed for " + path + ": No error message available.";
168133
}
169-
// ONLY print the userFriendlyError to System.err
170-
System.err.println(userFriendlyError);
134+
} catch (Exception jsonEx) {
135+
}
136+
return Optional.empty();
137+
}
138+
139+
/** Formats a user-friendly error string from a parsed JSON error object. */
140+
private String formatJsonError(JsonObject errorObj) {
141+
String title = errorObj.has("title") ? errorObj.get("title").getAsString() : "Error";
142+
int errorCode = errorObj.has("errorCode") ? errorObj.get("errorCode").getAsInt() : -1;
143+
String description = parseJsonDescription(errorObj);
144+
145+
StringBuilder improvedError =
146+
new StringBuilder()
147+
.append("RDAP Request Failed (Code ")
148+
.append(errorCode)
149+
.append("): ")
150+
.append(title);
151+
if (!Strings.isNullOrEmpty(description)) {
152+
improvedError.append("\n Description: ").append(description);
153+
}
154+
return improvedError.toString();
155+
}
156+
157+
/** Extracts and formats the 'description' field from a JSON error object. */
158+
private String parseJsonDescription(JsonObject errorObj) {
159+
if (!errorObj.has("description")) {
160+
return "";
161+
}
162+
JsonElement descElement = errorObj.get("description");
163+
if (descElement.isJsonArray()) {
164+
StringBuilder sb = new StringBuilder();
165+
for (JsonElement element : descElement.getAsJsonArray()) {
166+
if (sb.length() > 0) sb.append("\n ");
167+
sb.append(element.getAsString());
168+
}
169+
return sb.toString();
170+
} else if (descElement.isJsonPrimitive()) {
171+
return descElement.getAsString();
172+
}
173+
return "";
174+
}
175+
176+
/** Formats a fallback error message when JSON parsing fails. */
177+
private String formatFallbackError(String path, String errorMessage) {
178+
if (errorMessage.contains(": 501 Not Implemented")) {
179+
return "RDAP Request Failed (Code 501): Not Implemented\n"
180+
+ " Description: The query for '"
181+
+ path
182+
+ "' was understood, but is not implemented by this registry.";
183+
} else if (errorMessage.contains(": 404 Not Found")) {
184+
return "RDAP Request Failed (Code 404): Not Found\n"
185+
+ " Description: The resource at path '"
186+
+ path
187+
+ "' does not exist or no results matched the query.";
188+
} else if (errorMessage.contains(": 422 Unprocessable Entity")) {
189+
return "RDAP Request Failed (Code 422): Unprocessable Entity\n"
190+
+ " Description: The server understood the request, but cannot process the"
191+
+ " included entities.";
192+
} else if (errorMessage.contains(": 500 Internal Server Error")) {
193+
return "RDAP Request Failed (Code 500): Internal Server Error\n"
194+
+ " Description: An unexpected error occurred on the server. Check server logs"
195+
+ " for details.";
196+
} else if (errorMessage.contains(": 503 Service Unavailable")) {
197+
return "RDAP Request Failed (Code 503): Service Unavailable\n"
198+
+ " Description: The RDAP service is temporarily unavailable. Please try again later.";
199+
} else {
200+
String rawMessage = errorMessage.substring(0, Math.min(errorMessage.length(), 150));
201+
return "Request failed for " + path + ": " + rawMessage;
171202
}
172203
}
173204

174205
/** Recursively formats a JsonElement into a human-readable, indented, key-value string. */
175206
private String formatJsonElement(JsonElement element, String indent) {
176207
StringBuilder sb = new StringBuilder();
177208
if (element == null || element.isJsonNull()) {
178-
// Omit nulls for cleaner output
179209
} else if (element.isJsonObject()) {
180210
JsonObject obj = element.getAsJsonObject();
181211
obj.entrySet().stream()
182-
.sorted(Map.Entry.comparingByKey()) // Sort keys for consistent output
212+
.sorted(Map.Entry.comparingByKey())
183213
.forEach(
184214
entry -> {
185215
if (!entry.getValue().isJsonNull()) {
@@ -208,4 +238,4 @@ private String formatJsonElement(JsonElement element, String indent) {
208238
}
209239
return sb.toString();
210240
}
211-
}
241+
}

core/src/main/java/google/registry/tools/RegistryToolComponent.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ interface RegistryToolComponent {
136136
void inject(PendingEscrowCommand command);
137137

138138
void inject(RdapQueryCommand command);
139+
139140
void inject(RenewDomainCommand command);
140141

141142
void inject(SaveSqlCredentialCommand command);

0 commit comments

Comments
 (0)