处理异常的原因有所不同

时间:2016-06-16 07:21:02

标签: java exception

在我的一个软件中,我使用的库基本上是一个协议实现。该库根据五个第一OSI层(物理到会话)构建。

我必须使用具有此接口的会话层

public interface ReadSession {
    Iterable<byte[]> read(boolean fromStart, byte dataset, int nbData) throws SessionException;
}

现在我的问题是,根据内部(或内部的内部等)原因,我需要我的软件表现不同。

示例(&gt;代表内部原因关系):

如果SessionException > IOException > ...那么我应该中止所有通信

如果SessionException > TransportException > NetworkException > ...,那么我应该记录异常并继续进行下一次通信

如果SessionException > TransportException > GatewayException > ...,那么我应警告用户其网关存在问题

但我现在所拥有的只是一次捕获

catch(SessionException e) {
    //How to handle this problematic properly ?
}

我觉得自己对拨打getCause()的固定号码感到不舒服,因为:

  • 涉及大量空检查
  • 我依赖于库的实现细节(leaky abstraction),如果将来这些改变我搞砸了

有没有人已经遇到过这样的情况,并想分享他如何尽可能干净地处理它的知识?

2 个答案:

答案 0 :(得分:2)

这里的一种方法是在单个catch块中创建一个原因列表。

例如

catch (SessionException t)
{
    List<String> causeList = new ArrayList<>();
    do
    {
        causeList.add(t.getClass().getName());
        t = t.getCause();

    } while(t != null);
}

然后您可以做的是将causeList与您硬编码的一组预定义原因列表进行比较。当您发现causeList等于其中一个预定义列表时,则会采用相应的代码路径。

预定义列表可能类似于:

final List<String> ABORT_LIST = new ArrayList<String>
   (Arrays.asList("com.package.SessionException", "java.io.IOException"));

然后,在catch块中构建causeList之后,您可以执行以下操作:

if (causeList.equals(ABORT_LIST))
{
    System.out.println("Aborting...");
}

答案 1 :(得分:0)

我最终使用了这样的东西:

catch(SessionException e) {
    Throwable cause = e.getCause();
    while(cause != null) {
        if(cause instanceof NetworkException.class) {
            //Trigger some logic
        }
        else if(...)
        cause = cause.getCause();
    }
}