这是个糟糕的主意扔异常RemoteExceptions时使用异常链?我们有做这样的事情的RMI服务器:

public Object doSomething() throws RemoteException
{
    try
    {
        return getData();
    }
    catch (CustomException ex)
    {
        throw new RemoteException(ex);
    }
}

我越来越引起了我的客户一个ClassNotFoundException UnmarshallException。从积极的一面,事实证明,CustomException本身就是出口。不幸的是,另一个异常内心深处,这家伙不是出口,这是其中的ClassNotFoundException进来我想层次是这样的:

的RemoteException - > CustomException - >的SQLException - > NotExportedException

我看到的问题是,即使我们可以保证CustomException出口,我们不能保证任何下级例外。

我倾向于使用从未有例外,因为这个异常RemoteExceptions链接。相反,我想我大概应该记录在服务器端的堆栈跟踪,并抛出一个普通的,香草的RemoteException没有“原因”异常链接到它。任何人处理这个情况之前?

有帮助吗?

解决方案

而不是RemoteException的包装CustomException,您可以修改您的远程接口是这样的:

interface Foo extends Remote {

  Object doSomething() throws CustomException, RemoteException;

}

这里的原则是,只有RMI运行时应该是提高异常RemoteExceptions;他们在信号远程处理某些故障,而不是在应用程序逻辑。实际上,具体的实现甚至不需要申报RemoteException

但是,这不处理您的服务正赶上从一些第三方库的例外情况,但不希望公开,在一个throws子句。

public Object doSomething() throws CustomException {
  try {
    return theirSvc.getData();
  } catch (ThirdPartyException ex) {
    throw new CustomException("Failed to obtain requested data.");
    // or: throw new CustomException("Failed to obtain requested data.", ex) ?
  }
}

在这种情况下,我建议你不要创建一个“漏抽象”,其中一个依赖将在客户端,否则也没必要知道第三方库中创建。

通常情况下,记录的的投掷是不好的做法,因为同样的错误被重复记录。但是,在这种情况下,我认为这是有道理的,因为抛出的异常被运送到客户端;它可能是在客户端和服务器登录它都是有用的。所以catch块最终看起来像这样:

catch (ThirdPartyException ex) {
   String message = "Failed to obtain requested data.";
   log.error(message, ex);
   throw new CustomException(message);
 }

此方式,ThirdPartyException依赖性被限制到服务器,服务器日志包含适当的执行相关的信息,并且该错误被正确地报告给客户端。

其他提示

我们捕获来自源异常消息+整个堆栈跟踪,并通过该上作为远程异常的内容。这样,你得到所有的堆细节,但你不必担心任何的任何内部的例外是不可序列化的。

您永远不知道还有什么其他的对象可能是一些其他第三方内(甚至是你自己的“第一方”自定义异常!)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top