From 1ad7230baa13d92f168e8bba3d8ae6d588d3dd8e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Oct 2024 22:27:13 +0530 Subject: [PATCH 1/2] Standardise the Engine JSON-RPC error codes --- .../web3j/JsonRpcErrorCodes.java | 47 +++++++++++++++++++ .../executionclient/web3j/Web3JClient.java | 31 +++++++++--- 2 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java new file mode 100644 index 00000000000..0e32f5c862e --- /dev/null +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java @@ -0,0 +1,47 @@ +package tech.pegasys.teku.ethereum.executionclient.web3j; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public final class JsonRpcErrorCodes { + public static final int PARSE_ERROR = -32700; + public static final int INVALID_REQUEST = -32600; + public static final int METHOD_NOT_FOUND = -32601; + public static final int INVALID_PARAMS = -32602; + public static final int INTERNAL_ERROR = -32603; + public static final int SERVER_ERROR_RANGE_START = -32000; + public static final int SERVER_ERROR_RANGE_END = -32099; + + private static final Map ERROR_MESSAGES; + + static { + Map messages = new HashMap<>(); + messages.put(PARSE_ERROR, "Parse error"); + messages.put(INVALID_REQUEST, "Invalid request"); + messages.put(METHOD_NOT_FOUND, "Method not found"); + messages.put(INVALID_PARAMS, "Invalid params"); + messages.put(INTERNAL_ERROR, "Internal error"); + messages.put(SERVER_ERROR_RANGE_START, "Server error"); + ERROR_MESSAGES = Collections.unmodifiableMap(messages); + } + + private JsonRpcErrorCodes() { + // Utility class, do not instantiate + } + + public static String getErrorMessage(int errorCode) { + if (isServerError(errorCode)) { + return ERROR_MESSAGES.get(SERVER_ERROR_RANGE_START); + } + return ERROR_MESSAGES.getOrDefault(errorCode, "Unknown error"); + } + + public static boolean isServerError(int errorCode) { + return errorCode >= SERVER_ERROR_RANGE_END && errorCode <= SERVER_ERROR_RANGE_START; + } + + public static boolean isStandardError(int errorCode) { + return ERROR_MESSAGES.containsKey(errorCode) || isServerError(errorCode); + } +} \ No newline at end of file diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java index b8cf68f6729..d6ee5dfa3ff 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java @@ -86,14 +86,9 @@ public SafeFuture> doRequest( (response, exception) -> { final boolean isCriticalRequest = isCriticalRequest(web3jRequest); if (exception != null) { - final boolean couldBeAuthError = isAuthenticationException(exception); - handleError(isCriticalRequest, exception, couldBeAuthError); - return Response.withErrorMessage(getMessageOrSimpleName(exception)); + return handleException(exception, isCriticalRequest); } else if (response.hasError()) { - final String errorMessage = - response.getError().getCode() + ": " + response.getError().getMessage(); - handleError(isCriticalRequest, new IOException(errorMessage), false); - return Response.withErrorMessage(errorMessage); + return handleJsonRpcError(response.getError(), isCriticalRequest); } else { handleSuccess(isCriticalRequest); return new Response<>(response.getResult()); @@ -101,6 +96,28 @@ public SafeFuture> doRequest( }); } + private Response handleException(Throwable exception, boolean isCriticalRequest) { + final boolean couldBeAuthError = isAuthenticationException(exception); + handleError(isCriticalRequest, exception, couldBeAuthError); + return Response.withErrorMessage(getMessageOrSimpleName(exception)); + } + + private Response handleJsonRpcError(org.web3j.protocol.core.Response.Error error, boolean isCriticalRequest) { + int errorCode = error.getCode(); + String errorType = JsonRpcErrorCodes.getErrorMessage(errorCode); + String formattedError = String.format("%s (%d): %s", errorType, errorCode, error.getMessage()); + + if (isCriticalRequest) { + logError(formattedError); + } + + return Response.withErrorMessage(formattedError); + } + + private void logError(String errorMessage) { + eventLog.executionClientRequestFailed(new Exception(errorMessage),false); + } + private boolean isCriticalRequest(final Request request) { return !nonCriticalMethods.contains(request.getMethod()); } From 67bcc085375e8cb6610979f6c657a799d83162f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 10 Oct 2024 00:03:52 +0530 Subject: [PATCH 2/2] fix CircleCI assemble and spotless checks --- .../web3j/JsonRpcErrorCodes.java | 87 +++++++++++-------- .../executionclient/web3j/Web3JClient.java | 10 +-- 2 files changed, 55 insertions(+), 42 deletions(-) diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java index 0e32f5c862e..cc08bcc116e 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/JsonRpcErrorCodes.java @@ -1,3 +1,16 @@ +/* + * Copyright Consensys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + package tech.pegasys.teku.ethereum.executionclient.web3j; import java.util.Collections; @@ -5,43 +18,43 @@ import java.util.Map; public final class JsonRpcErrorCodes { - public static final int PARSE_ERROR = -32700; - public static final int INVALID_REQUEST = -32600; - public static final int METHOD_NOT_FOUND = -32601; - public static final int INVALID_PARAMS = -32602; - public static final int INTERNAL_ERROR = -32603; - public static final int SERVER_ERROR_RANGE_START = -32000; - public static final int SERVER_ERROR_RANGE_END = -32099; - - private static final Map ERROR_MESSAGES; - - static { - Map messages = new HashMap<>(); - messages.put(PARSE_ERROR, "Parse error"); - messages.put(INVALID_REQUEST, "Invalid request"); - messages.put(METHOD_NOT_FOUND, "Method not found"); - messages.put(INVALID_PARAMS, "Invalid params"); - messages.put(INTERNAL_ERROR, "Internal error"); - messages.put(SERVER_ERROR_RANGE_START, "Server error"); - ERROR_MESSAGES = Collections.unmodifiableMap(messages); - } - - private JsonRpcErrorCodes() { - // Utility class, do not instantiate + public static final int PARSE_ERROR = -32700; + public static final int INVALID_REQUEST = -32600; + public static final int METHOD_NOT_FOUND = -32601; + public static final int INVALID_PARAMS = -32602; + public static final int INTERNAL_ERROR = -32603; + public static final int SERVER_ERROR_RANGE_START = -32000; + public static final int SERVER_ERROR_RANGE_END = -32099; + + private static final Map ERROR_MESSAGES; + + static { + Map messages = new HashMap<>(); + messages.put(PARSE_ERROR, "Parse error"); + messages.put(INVALID_REQUEST, "Invalid request"); + messages.put(METHOD_NOT_FOUND, "Method not found"); + messages.put(INVALID_PARAMS, "Invalid params"); + messages.put(INTERNAL_ERROR, "Internal error"); + messages.put(SERVER_ERROR_RANGE_START, "Server error"); + ERROR_MESSAGES = Collections.unmodifiableMap(messages); + } + + private JsonRpcErrorCodes() { + // Utility class, do not instantiate + } + + public static String getErrorMessage(final int errorCode) { + if (isServerError(errorCode)) { + return ERROR_MESSAGES.get(SERVER_ERROR_RANGE_START); } + return ERROR_MESSAGES.getOrDefault(errorCode, "Unknown error"); + } - public static String getErrorMessage(int errorCode) { - if (isServerError(errorCode)) { - return ERROR_MESSAGES.get(SERVER_ERROR_RANGE_START); - } - return ERROR_MESSAGES.getOrDefault(errorCode, "Unknown error"); - } + public static boolean isServerError(final int errorCode) { + return errorCode >= SERVER_ERROR_RANGE_END && errorCode <= SERVER_ERROR_RANGE_START; + } - public static boolean isServerError(int errorCode) { - return errorCode >= SERVER_ERROR_RANGE_END && errorCode <= SERVER_ERROR_RANGE_START; - } - - public static boolean isStandardError(int errorCode) { - return ERROR_MESSAGES.containsKey(errorCode) || isServerError(errorCode); - } -} \ No newline at end of file + public static boolean isStandardError(final int errorCode) { + return ERROR_MESSAGES.containsKey(errorCode) || isServerError(errorCode); + } +} diff --git a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java index d6ee5dfa3ff..674fab6abac 100644 --- a/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java +++ b/ethereum/executionclient/src/main/java/tech/pegasys/teku/ethereum/executionclient/web3j/Web3JClient.java @@ -15,7 +15,6 @@ import static tech.pegasys.teku.infrastructure.exceptions.ExceptionUtil.getMessageOrSimpleName; -import java.io.IOException; import java.net.ConnectException; import java.time.Duration; import java.util.Collection; @@ -96,13 +95,14 @@ public SafeFuture> doRequest( }); } - private Response handleException(Throwable exception, boolean isCriticalRequest) { + private Response handleException(final Throwable exception, final boolean isCriticalRequest) { final boolean couldBeAuthError = isAuthenticationException(exception); handleError(isCriticalRequest, exception, couldBeAuthError); return Response.withErrorMessage(getMessageOrSimpleName(exception)); } - private Response handleJsonRpcError(org.web3j.protocol.core.Response.Error error, boolean isCriticalRequest) { + private Response handleJsonRpcError( + final org.web3j.protocol.core.Response.Error error, final boolean isCriticalRequest) { int errorCode = error.getCode(); String errorType = JsonRpcErrorCodes.getErrorMessage(errorCode); String formattedError = String.format("%s (%d): %s", errorType, errorCode, error.getMessage()); @@ -114,8 +114,8 @@ private Response handleJsonRpcError(org.web3j.protocol.core.Response.Erro return Response.withErrorMessage(formattedError); } - private void logError(String errorMessage) { - eventLog.executionClientRequestFailed(new Exception(errorMessage),false); + private void logError(final String errorMessage) { + eventLog.executionClientRequestFailed(new Exception(errorMessage), false); } private boolean isCriticalRequest(final Request request) {