后端自定义的异常 在dubbo 怎么抛到前端
4个回答
展开全部
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
try {
Result result = invoker.invoke(invocation);
if (result.hasException() && GenericService.class != invoker.getInterface()) {
try {
Throwable exception = result.getException();
// 如果是checked异常,直接抛出
if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) {
return result;
}
// 在方法签名上有声明,直接抛出
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;
}
// 未在方法签名上定义的异常,在服务器端打印ERROR日志
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);
// 异常类和接口类在同一jar包里,直接抛出
String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)){
return result;
}
// 是JDK自带的异常,直接抛出
String className = exception.getClass().getName();
if (className.startsWith("java.") || className.startsWith("javax.")) {
return result;
}
// 是Dubbo本身的异常,直接抛出
if (exception instanceof RpcException) {
return result;
}
// 否则,包装成RuntimeException抛给客户端
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;
}
}
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;
}
}
所以在dubbo的service端想抛出自定义异常,只能通过在service端的接口方法上声明所要抛出的异常,或者将异常类与接口同包,再或者是接口的实现类再实现dubbo的GenericService接口。
对于第一种方案没有使用,因为它对代码的入侵比较严重。
第二种方案可以实现,可对于目前的业务框架,让接口类和异常类同包则变得不太可能。
所以最后选择了让接口实现类再实现GenericService接口,而对于其需要实现的$invoke方法则没有做任何的方法体处理,直接废弃。
对于dubbo的service端自定义异常类的处理,有些不理解的就是,为什么dubbo需要对自定义异常类做一次Runtime异常的转化,而不是直接抛出原异常类型。或者有没有对dubbo更了解的朋友,有对自定义异常更好的处理方法。
try {
Result result = invoker.invoke(invocation);
if (result.hasException() && GenericService.class != invoker.getInterface()) {
try {
Throwable exception = result.getException();
// 如果是checked异常,直接抛出
if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) {
return result;
}
// 在方法签名上有声明,直接抛出
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;
}
// 未在方法签名上定义的异常,在服务器端打印ERROR日志
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);
// 异常类和接口类在同一jar包里,直接抛出
String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)){
return result;
}
// 是JDK自带的异常,直接抛出
String className = exception.getClass().getName();
if (className.startsWith("java.") || className.startsWith("javax.")) {
return result;
}
// 是Dubbo本身的异常,直接抛出
if (exception instanceof RpcException) {
return result;
}
// 否则,包装成RuntimeException抛给客户端
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;
}
}
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;
}
}
所以在dubbo的service端想抛出自定义异常,只能通过在service端的接口方法上声明所要抛出的异常,或者将异常类与接口同包,再或者是接口的实现类再实现dubbo的GenericService接口。
对于第一种方案没有使用,因为它对代码的入侵比较严重。
第二种方案可以实现,可对于目前的业务框架,让接口类和异常类同包则变得不太可能。
所以最后选择了让接口实现类再实现GenericService接口,而对于其需要实现的$invoke方法则没有做任何的方法体处理,直接废弃。
对于dubbo的service端自定义异常类的处理,有些不理解的就是,为什么dubbo需要对自定义异常类做一次Runtime异常的转化,而不是直接抛出原异常类型。或者有没有对dubbo更了解的朋友,有对自定义异常更好的处理方法。
展开全部
自定义一个异常,比如tempException 怎么在provide 抛给 consumer。 现在抛的时候 dubbo ExceptionFilter Wrap一层RuntimeException。
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2017-07-20
展开全部
大致格式如下:try{AdoConnection.CreateInstance(__uuidof(Connection));//初始化Connection对象实例AdoSet.CreateInstance(__uuidof(Recordset));//初始化Recordset对象实例HRESULThr=AdoConnection->Open(strConnect.GetBuffer(),"","",adOpenForwardOnly);if(!SUCCEEDED(hr)){returnfalse;}CStringstrSql=_T("");strSql="SELECT*FROM表名WHERE条件";hr=AdoSet->Open(strSql.GetBuffer(),AdoConnection.GetInterfacePtr(),adOpenForwardOnly,adLockReadOnly,adCmdText);if(!SUCCEEDED(hr)){returnfalse;}AdoSet->MoveFirst();while(!AdoSet->adoEOF){try{var=AdoFieldsPtr->Item["列名"]->Value;if(var.vt!=VT_NULL){//用这个值}}catch()//捕获所有错误{//此处调用回滚..//.return;}AdoSet->MoveNext();}}catch(){AdoSet->Close();//关闭数据集AdoConnection->Close();//关闭数据库的连接returnfalse;}AdoSet->Close();//关闭数据集AdoConnection->Close();//关闭数据库的连接
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
自定义一个异常,比如tempException 怎么在provide 抛给 consumer。 现在抛的时候 dubbo ExceptionFilter Wrap一层RuntimeException。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询