【问题标题】:Handling errors coming from gateway implementation in the use case - Clean Architecture处理来自用例中网关实现的错误 - 清洁架构
【发布时间】:2020-02-08 19:36:11
【问题描述】:

当我们使用 Onion 架构构建软件时,如何处理来自网关实现的异常?

为了澄清,我创建了一个使用 Java 和 SpringBoot 的示例:

@Component
@AllArgsConstructor
public class SaveAddressUseCase{
    private final GetCustomerGateway getCustomerGateway;

    public void execute(AddressDomain address, Long customerId){
        try{
            //validates the customerId supplied and returns the customer from an external service.
            CustomerDomain customer = getCustomerGateway.execute(customerId);
            address.setCustomer(customer);
            //saves the address
        }catch(CustomerNotFoundException ex) {
            AddressErrorDomain addressErrorDomain = new AddressErrorDomain();
            //saves the address in a error table with httpStatus 404
        } catch (InternalErrorException ex) {
            AddressErrorDomain addressErrorDomain = new AddressErrorDomain();
            //save the address in a error table with httpStatus 500
        }
    }
}

这是一个简单的用例,它将保存一个地址,但首先,它需要从外部服务获取该地址的客户。如果没有找到客户,我需要将地址保存在错误表中以便以后处理。如果此外部服务已关闭,情况也是如此,但区分这两个错误很重要,我可以使用从我的 API 调用返回的 HttpStatus 处理此问题。

public interface GetCustomerGateway {
   CustomerDomain execute(Long customerId);
}

@Component
@AllArgsConstructor
public class GetCustomerGatewayImpl implements GetCustomerGateway {
    private final CustomerApi customerApi; //Feign interface to call an external service

    public CustomerDomain execute(Long customerId){
        try{
            return customerApi.getCustomerById(customerId);
        }catch(FeignException ex){
            if (ex.status() == HttpStatus.NOT_FOUND.value()) {
                throw new CustomerNotFoundException();
            } else {
                throw new InternalErrorException();
            }
        }
    }
}

最后,这是我的网关实现,它使用一个简单的 Feign 接口调用这个外部服务,并抛出两个我从 RuntimeException 扩展而来的自定义异常。

问题:在用例中捕获这两个异常我不是在处理只有网关必须知道的细节吗?或者更糟糕的是,我没有使用异常来控制我的应用程序的流程?如何以比示例中更好的方式处理来自网关实现的错误?

Obs:在这个例子中,将地址保存在错误表中很重要,以免破坏客户端的用户体验,我还需要区分这些错误。

提前致谢!

【问题讨论】:

    标签: java spring-boot architecture clean-architecture onion-architecture


    【解决方案1】:

    考虑使用@ControllerAdvice 来保持控制器的清洁和专注

    @ControllerAdvice
    @Slf4j
    public class RestExceptionHandler {
    //Magic happens here
    }
    

    在 RestExceptionHandler 中,你可以像这样捕获所有的假装异常,并随心所欲地处理它们

        @ResponseBody
        @ExceptionHandler(Throwable.class)
        public final ResponseEntity<?> handleFeignExceptions(Exception ex, WebRequest request) {
    
            if (ex instanceof FeignException) {
    
                return handle((FeignException) ex);// define your custom handle method
            }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-15
      • 2020-12-12
      • 2022-05-18
      • 1970-01-01
      • 1970-01-01
      • 2021-02-12
      • 2021-10-16
      • 2017-03-20
      相关资源
      最近更新 更多