Current location - Quotes Website - Personality signature - How to throw custom exceptions in the backend to the frontend in dubbo
How to throw custom exceptions in the backend to the frontend in dubbo

public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {

try {

Result result = invoker.invoke(invocation);< /p>

if (result.hasException() && GenericService.class != invoker.getInterface()) {

try {

Throwable exception = result.getException() ;

//If it is a checked exception, throw it directly

if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) {

return result ;

}

//There is a statement in the method signature, throw it directly

try {

Method method = invoker.getInterface ().getMethod(invocation.getMethodName(), invocation.getParameterTypes());

Class[] exceptionClassses = method.getExceptionTypes();

for (Class< ?> exceptionClass : exceptionClassses) {

if (exception.getClass().equals(exceptionClass)) {

return result;

}

}

} catch (NoSuchMethodException e) {

return result;

}

// not on method signature For defined exceptions, print the ERROR log on the server side

logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()

+ " . service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()

+ ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);

// The exception class and the interface class are in the same jar package and are thrown directly

String serviceFile = ReflectUtils.getCodeBase( invoker.getInterface());

String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());

if (serviceFile == null || exceptionFile == null || serviceFile .equals(exceptionFile)){

return result;

}

// It is the exception that comes with JDK and is thrown directly

String className = exception.getClass().getName();

if (className.startsWith("java.") || className.startsWith("javax.")) {

< p>return result;

}

// It is Dubbo's own exception, thrown directly

if (exception instanceof RpcException) {

< p>return result;

}

// Otherwise, wrap it into a RuntimeException and throw it to the client

return new RpcResult(new RuntimeException(StringUtils.toString(exception )));

} catch (Throwable e) {

logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()

+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()

+ ", exception: " + e.getClass( ).getName() + ": " + e.getMessage(), e);

return result;

}

}

< p>return result;

} catch (RuntimeException e) {

logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()

+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()

+ ", exception: " + e .getClass().getName() + ": " + e.getMessage(), e);

throw e;

}

}

So if you want to throw a custom exception on dubbo's service side, you can only declare the exception to be thrown on the interface method of the service side, or package the exception class with the interface, or use the implementation class of the interface Then implement dubbo's GenericService interface.

The first solution is not used because it causes serious intrusion into the code.

The second solution can be implemented, but with the current business framework, it is impossible to package the interface class and exception class in the same package.

So in the end, I chose to let the interface implementation class implement the GenericService interface, and the $invoke method that needs to be implemented does not do any method body processing and is directly discarded.

What I don’t understand about dubbo’s service-side custom exception class processing is why dubbo needs to convert the custom exception class into a runtime exception instead of directly throwing the original exception type. Or is there anyone who knows more about dubbo and has a better way to handle custom exceptions.