Skip to content

feat(jsonrpc): jsonrpc set error resolver #6369

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: release_v4.8.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/src/main/java/org/tron/common/utils/ByteArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.util.encoders.Hex;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;

/*
* Copyright (c) [2016] [ <ether.camp> ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.tron.core.exception.jsonrpc;

import lombok.Getter;
import org.tron.core.exception.TronException;

@Getter
public class JsonRpcException extends TronException {
private Object data = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not define data's type as byte[] ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object is more general than byte[], I think

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, use the Object type because it is more flexible and can support various kinds of data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get it.


public JsonRpcException() {
super();
report();
}

public JsonRpcException(String message, Object data) {
super(message);
this.data = data;
report();
}

public JsonRpcException(String message) {
super(message);
report();
}

public JsonRpcException(String message, Throwable cause) {
super(message, cause);
report();
}


}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.tron.core.exception;
package org.tron.core.exception.jsonrpc;

public class JsonRpcInternalException extends TronException {
public class JsonRpcInternalException extends JsonRpcException {

public JsonRpcInternalException() {
super();
Expand All @@ -13,4 +13,8 @@ public JsonRpcInternalException(String message) {
public JsonRpcInternalException(String message, Throwable cause) {
super(message, cause);
}

public JsonRpcInternalException(String message, Object data) {
super(message, data);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.tron.core.exception;
package org.tron.core.exception.jsonrpc;

public class JsonRpcInvalidParamsException extends TronException {
public class JsonRpcInvalidParamsException extends JsonRpcException {

public JsonRpcInvalidParamsException() {
super();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.tron.core.exception;
package org.tron.core.exception.jsonrpc;

public class JsonRpcInvalidRequestException extends TronException {
public class JsonRpcInvalidRequestException extends JsonRpcException {

public JsonRpcInvalidRequestException() {
super();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.tron.core.exception;
package org.tron.core.exception.jsonrpc;

public class JsonRpcMethodNotFoundException extends TronException {
public class JsonRpcMethodNotFoundException extends JsonRpcException {

public JsonRpcMethodNotFoundException() {
super();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.tron.core.exception;
package org.tron.core.exception.jsonrpc;

public class JsonRpcTooManyResultException extends TronException {
public class JsonRpcTooManyResultException extends JsonRpcException {

public JsonRpcTooManyResultException() {
super();
Expand Down
2 changes: 1 addition & 1 deletion framework/src/main/java/org/tron/core/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@
import org.tron.core.exception.DupTransactionException;
import org.tron.core.exception.HeaderNotFound;
import org.tron.core.exception.ItemNotFoundException;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.NonUniqueObjectException;
import org.tron.core.exception.PermissionException;
import org.tron.core.exception.SignatureFormatException;
Expand All @@ -188,6 +187,7 @@
import org.tron.core.exception.VMIllegalException;
import org.tron.core.exception.ValidateSignatureException;
import org.tron.core.exception.ZksnarkException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.net.TronNetDelegate;
import org.tron.core.net.TronNetService;
import org.tron.core.net.message.adv.TransactionMessage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.tron.common.utils.Sha256Hash;
import org.tron.common.utils.StringUtil;
import org.tron.core.Wallet;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.protos.Protocol.Block;
import org.tron.protos.Protocol.Transaction;
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.tron.core.services.jsonrpc;

import com.fasterxml.jackson.databind.JsonNode;
import com.googlecode.jsonrpc4j.ErrorData;
import com.googlecode.jsonrpc4j.ErrorResolver;
import com.googlecode.jsonrpc4j.JsonRpcError;
import com.googlecode.jsonrpc4j.JsonRpcErrors;
import com.googlecode.jsonrpc4j.ReflectionUtil;
import java.lang.reflect.Method;
import java.util.List;
import org.tron.core.exception.jsonrpc.JsonRpcException;

/**
* {@link ErrorResolver} that uses annotations.
*/
public enum JsonRpcErrorResolver implements ErrorResolver {
INSTANCE;

/**
* {@inheritDoc}
*/
@Override
public JsonError resolveError(
Throwable thrownException, Method method, List<JsonNode> arguments) {
JsonRpcError resolver = getResolverForException(thrownException, method);
if (notFoundResolver(resolver)) {
return null;
}

String message = hasErrorMessage(resolver) ? resolver.message() : thrownException.getMessage();

// data priority: exception > annotation > default ErrorData
Object data = hasErrorData(resolver)
? resolver.data()
: new ErrorData(resolver.exception().getName(), message);

// Use data from JsonRpcException if present
if (thrownException instanceof JsonRpcException
&& ((JsonRpcException)thrownException).getData() != null) {
data = ((JsonRpcException)thrownException).getData();
}
return new JsonError(resolver.code(), message, data);
}

private JsonRpcError getResolverForException(Throwable thrownException, Method method) {
JsonRpcErrors errors = ReflectionUtil.getAnnotation(method, JsonRpcErrors.class);
if (hasAnnotations(errors)) {
for (JsonRpcError errorDefined : errors.value()) {
if (isExceptionInstanceOfError(thrownException, errorDefined)) {
return errorDefined;
}
}
}
return null;
}

private boolean notFoundResolver(JsonRpcError resolver) {
return resolver == null;
}

private boolean hasErrorMessage(JsonRpcError em) {
// noinspection ConstantConditions
return em.message() != null && !em.message().trim().isEmpty();
}

private boolean hasErrorData(JsonRpcError em) {
// noinspection ConstantConditions
return em.data() != null && !em.data().trim().isEmpty();
}

private boolean hasAnnotations(JsonRpcErrors errors) {
return errors != null;
}

private boolean isExceptionInstanceOfError(Throwable target, JsonRpcError em) {
return em.exception().isInstance(target);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void init(ServletConfig config) throws ServletException {
true);

rpcServer = new JsonRpcServer(compositeService);
rpcServer.setErrorResolver(JsonRpcErrorResolver.INSTANCE);

HttpStatusCodeProvider httpStatusCodeProvider = new HttpStatusCodeProvider() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import org.tron.common.utils.ByteArray;
import org.tron.core.exception.BadItemException;
import org.tron.core.exception.ItemNotFoundException;
import org.tron.core.exception.JsonRpcInternalException;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.JsonRpcInvalidRequestException;
import org.tron.core.exception.JsonRpcMethodNotFoundException;
import org.tron.core.exception.JsonRpcTooManyResultException;
import org.tron.core.exception.jsonrpc.JsonRpcInternalException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidRequestException;
import org.tron.core.exception.jsonrpc.JsonRpcMethodNotFoundException;
import org.tron.core.exception.jsonrpc.JsonRpcTooManyResultException;
import org.tron.core.services.jsonrpc.types.BlockResult;
import org.tron.core.services.jsonrpc.types.BuildArguments;
import org.tron.core.services.jsonrpc.types.CallArguments;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@
import org.tron.core.exception.ContractValidateException;
import org.tron.core.exception.HeaderNotFound;
import org.tron.core.exception.ItemNotFoundException;
import org.tron.core.exception.JsonRpcInternalException;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.JsonRpcInvalidRequestException;
import org.tron.core.exception.JsonRpcMethodNotFoundException;
import org.tron.core.exception.JsonRpcTooManyResultException;
import org.tron.core.exception.VMIllegalException;
import org.tron.core.exception.jsonrpc.JsonRpcInternalException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidRequestException;
import org.tron.core.exception.jsonrpc.JsonRpcMethodNotFoundException;
import org.tron.core.exception.jsonrpc.JsonRpcTooManyResultException;
import org.tron.core.services.NodeInfoService;
import org.tron.core.services.http.JsonFormat;
import org.tron.core.services.http.Util;
Expand Down Expand Up @@ -473,7 +473,6 @@ private String call(byte[] ownerAddressByte, byte[] contractAddressByte, long va
}
result = ByteArray.toJsonHex(listBytes);
} else {
logger.error("trigger contract failed.");
String errMsg = retBuilder.getMessage().toStringUtf8();
byte[] resData = trxExtBuilder.getConstantResult(0).toByteArray();
if (resData.length > 4 && Hex.toHexString(resData).startsWith(ERROR_SELECTOR)) {
Expand All @@ -483,7 +482,12 @@ private String call(byte[] ownerAddressByte, byte[] contractAddressByte, long va
errMsg += ": " + msg;
}

throw new JsonRpcInternalException(errMsg);
if (resData.length > 0) {
throw new JsonRpcInternalException(errMsg, ByteArray.toJsonHex(resData));
} else {
throw new JsonRpcInternalException(errMsg);
}

}

return result;
Expand Down Expand Up @@ -644,7 +648,12 @@ public String estimateGas(CallArguments args) throws JsonRpcInvalidRequestExcept
errMsg += ": " + msg;
}

throw new JsonRpcInternalException(errMsg);
if (data.length > 0) {
throw new JsonRpcInternalException(errMsg, ByteArray.toJsonHex(data));
} else {
throw new JsonRpcInternalException(errMsg);
}

} else {

if (supportEstimateEnergy) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.apache.commons.lang3.ArrayUtils;
import org.tron.common.bloom.Bloom;
import org.tron.common.crypto.Hash;
import org.tron.core.exception.JsonRpcTooManyResultException;
import org.tron.core.exception.jsonrpc.JsonRpcTooManyResultException;
import org.tron.core.store.SectionBloomStore;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.tron.common.crypto.Hash;
import org.tron.common.runtime.vm.DataWord;
import org.tron.core.config.args.Args;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.services.jsonrpc.TronJsonRpc.FilterRequest;
import org.tron.protos.Protocol.TransactionInfo.Log;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.concurrent.LinkedBlockingQueue;
import lombok.Getter;
import org.tron.core.Wallet;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.services.jsonrpc.TronJsonRpc.FilterRequest;
import org.tron.core.services.jsonrpc.TronJsonRpc.LogFilterElement;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.tron.common.utils.ByteArray;
import org.tron.core.Wallet;
import org.tron.core.config.args.Args;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.services.jsonrpc.JsonRpcApiUtil;
import org.tron.core.services.jsonrpc.TronJsonRpc.FilterRequest;
import org.tron.protos.Protocol.Block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.tron.core.db.Manager;
import org.tron.core.exception.BadItemException;
import org.tron.core.exception.ItemNotFoundException;
import org.tron.core.exception.JsonRpcTooManyResultException;
import org.tron.core.exception.jsonrpc.JsonRpcTooManyResultException;
import org.tron.core.services.jsonrpc.TronJsonRpc.LogFilterElement;
import org.tron.protos.Protocol.TransactionInfo;
import org.tron.protos.Protocol.TransactionInfo.Log;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import org.apache.commons.lang3.StringUtils;
import org.tron.api.GrpcAPI.BytesMessage;
import org.tron.core.Wallet;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.JsonRpcInvalidRequestException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidRequestException;
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
import org.tron.protos.contract.SmartContractOuterClass.SmartContract;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import org.apache.commons.lang3.StringUtils;
import org.tron.api.GrpcAPI.BytesMessage;
import org.tron.core.Wallet;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.JsonRpcInvalidRequestException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidRequestException;
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
import org.tron.protos.contract.SmartContractOuterClass.SmartContract;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import org.tron.core.Wallet;
import org.tron.core.exception.ContractExeException;
import org.tron.core.exception.ContractValidateException;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.ReceiptCheckErrException;
import org.tron.core.exception.VMIllegalException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.services.NodeInfoService;
import org.tron.core.services.jsonrpc.TronJsonRpcImpl;
import org.tron.core.vm.config.ConfigLoader;
Expand Down
10 changes: 5 additions & 5 deletions framework/src/test/java/org/tron/core/CoreExceptionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@
import org.tron.core.exception.HeaderNotFound;
import org.tron.core.exception.HighFreqException;
import org.tron.core.exception.ItemNotFoundException;
import org.tron.core.exception.JsonRpcInternalException;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.JsonRpcInvalidRequestException;
import org.tron.core.exception.JsonRpcMethodNotFoundException;
import org.tron.core.exception.JsonRpcTooManyResultException;
import org.tron.core.exception.NonCommonBlockException;
import org.tron.core.exception.NonUniqueObjectException;
import org.tron.core.exception.P2pException;
Expand All @@ -56,6 +51,11 @@
import org.tron.core.exception.ValidateSignatureException;
import org.tron.core.exception.ZkProofValidateException;
import org.tron.core.exception.ZksnarkException;
import org.tron.core.exception.jsonrpc.JsonRpcInternalException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidRequestException;
import org.tron.core.exception.jsonrpc.JsonRpcMethodNotFoundException;
import org.tron.core.exception.jsonrpc.JsonRpcTooManyResultException;

public class CoreExceptionTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.ByteUtil;
import org.tron.common.utils.Commons;
import org.tron.core.exception.JsonRpcInvalidParamsException;
import org.tron.core.exception.jsonrpc.JsonRpcInvalidParamsException;
import org.tron.core.services.jsonrpc.JsonRpcApiUtil;
import org.tron.core.services.jsonrpc.TronJsonRpc.FilterRequest;
import org.tron.core.services.jsonrpc.filters.LogBlockQuery;
Expand Down
Loading