策略模式链路任务的抽象异常处理方案

1、流程概述

在这里插入图片描述

如上,交易系统会对接很多不同的第三方扣款服务,比如说paypal、onekpay等。交易系统向第三方扣款服务发出请求,然后会收到对应的信息。下层服务包含两个方法,链式调用,也就是第一个方法出错的话,第二个方法也会出错。比如说返回的是json信息,就会对这个json信息解析并处理。但是由于第三方服务的不可控,假如返回了一些非json数据的context,就会导致解析失败,返回null,但不会停止。这个错误的context会继续往下传递,进入到下一个方法,这个方法对这个错误的context处理,从而产生空指针。

所以会导致两个异常:1、第一个方法解析完json得到null,这个null会在被第一个方法的引用中报空指针;2、链式调用,两个方法虽然不会相互调用,但是都是用的同一个context,第一个方法的context已经有问题,所以第二个方法在context的处理上也会出问题,报空指针异常。

我方希望:1、屏蔽掉空指针异常,但如果情况频繁还是要上报;2、假如第一个方法出问题则直接终止链式任务。


2、简单的处理方法

在链式任务开始之前对context做判断,假如是有问题的则抛自定义异常,从而避免了直接抛空指针异常,接着返回,从而避免了链式任务的继续执行。


3、抽象的处理方法

上面的方法虽然简单有效,但有没有办法抽象出来。假如链式方法中出现了别的错误,我们同样希望对抛出自定义异常同时终止链式任务,那应该如何处理?

首先我们定义一个自定义非检查异常ChannelStopException,用于表示链路必须停止的异常,然后再定义一个ChannelMesAnalysisfailException,用于表示报文解析错误的异常,也就是上面讲的第一个链路方法中可能会出现的异常,同时继承ChannelStopException。

public class ChannelStopException extends RuntimeException 

public class ChannelMesAnalysisfailException extends ChannelStopException

然后我们进入到第一个链路方法中,对用于解析json的方法做一下改造,只要解析失败就抛出ChannelMesAnalysisfailException异常,并记录信息。

@Nullable
public static <T> T toBeanChannelMes(String json, Class<T> tClass) {
    try {
        return ObjectMapperConfig.OBJECT_MAPPER.readValue(json, tClass);
    } catch (Exception e) {
      	//抛出自定义异常
        throw new ChannelMesAnalysisfailException("channel message nullpointer");
    }
}

回到执行链路任务的方法,假如第一个链路方法报文解析失败,异常就会往上抛,直到执行链路的方法,我们在这个方法上捕获异常,接着进行判断,假如异常属于必须停止的子类,则直接返回,不执行下一个链路任务,否则做其他处理。

public static void linkExecute(LinkExecutor... executors) {
  	//依次遍历多个方法,在同一条链路顺序执行
    for (LinkExecutor executor : executors) {
        try {
            executor.execute();
        }catch (Exception e){
            if (e instanceof ChannelStopException){
              	//链路中其中一个方法抛出了异常,假如属于必须要停止链路的进行的,则直接返回
                log.error("渠道报文处理异常:{}",e.getMessage());
                return;
            }
            //不需要停止链路进行的,则处理但并不返回
            log.error(e.getMessage());
        }
    }
}

举个例子,第一个链路方法中假如还有其他异常,而且是对下一个链路方法有影响的,我们可以直接抛出针对这个异常的自定义异常,并且继承ChannelStopException,负责执行链路任务的方法捕获之后就可以停止。而假如发生的异常不影响第二个链路的继续执行,我们可以在负责执行链路任务的方法捕获之后的判断新增一条专门处理,而不是直接不执行第二条链路。再或者发生的异常不会影响第一个链路方法的继续执行,我们也可以在第一个链路方法中捕获,但不抛出。

总的来说,这种抽象的处理有两个好处:1、实现了对特定方法发生异常的监控;2、实现对这类链路方法的异常处理的抽象,假如别的异常需要及时停止的异常,我们可以直接继承ChannelStopException。以下是流程图。

在这里插入图片描述

  • 30
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值