报告应用程序服务层的错误

时间:2013-08-05 22:55:16

标签: spring-mvc error-handling domain-driven-design

我正在实现基于Spring MVC的Web应用程序,并围绕DDD概念进行组织。目前我尝试实现票务预订功能。客户可以看到特定活动可用的门票数量。然后,他可以输入要预订的票数并提交表格。控制器接收请求,该控制器调用负责注册的应用服务。应用服务逻辑如下:

  1. 验证传入参数:
    • 1A。检查具有给定ID的事件是否存在
    • 1B。检查可用的门票数量是否允许预订
  2. 如果验证通过,请继续注册;否则,报告错误。
  3. 我对报告验证错误的正确方法有所怀疑 - 特别是对于第1B点。门票数量不允许预订的情况不是很不寻常。客户可以看到与数据库中当前票数不完全同步的票数(最终一致性) - 其他一些人可以在此期间预订一些票。

    最初我考虑通过抛出一些特定的例外来报告这些问题。但是,我可以想到其他几个有问题的情况,并且每个问题都有一个例外情况听起来不太好。

    我正在考虑的另一个选项是抛出一种包含错误代码的异常。但是,我不知道如何正确处理Spring MVC中的这种情况。

    此类问题的最佳做法是什么?你如何在MVC应用程序中处理它们?任何建议都非常感谢。

1 个答案:

答案 0 :(得分:1)

我认为这些是无法恢复的业务约束。

我目前的解决方案是Exception hierachy。

public abstract class UncheckedApplicationException extends RuntimeException {

    //omitted factory methods and constructors
    public abstract String getStatusCode();

    public abstract String getI18nCode();//ignore this if you don't need i18n    

    public abstract String[] getI18nArgs();//ignore this if you don't need i18n 
}

任何自定义异常都会扩展此异常。我认为这可以避免这样的代码:

try {  
    //invoke your application service
} catch (InsufficientInventoryException e) {  
    statusCode = INSUFFICIENT_INVENTORY;  
} catch (ExpriedPriceException e) {  
    statusCode = EXPIRED_PRICE;  
} catch (NoSuchProductException e) {  
    statusCode = NO_SUCH_PRODUCT;  
} catch (Exception e) {  
    statusCode = UNKNOWN;  
}

控制器代码段:

try {  
    //invoke your application service here 
    statusCode = SUCCESS;
    message = messageSource.getSuccess(locale));
} catch (UncheckedApplicationException e) {  
    statusCode = e.getStatusCode();  
    message = messageSource.getMessage(e, locale));
} catch (Exception e) {  
    statusCode = UNKNOWN;  
    message = messageSource.getUnknownError(e, locale));
}
//add statusCode & message to modelAttribute

如果您的Controller组织良好(但非常困难),您可以使用@ExceptionHandler来减少样板试管代码。

使用Excepton的另一个原因是应用程序服务通常用于分隔事务边界。如果要回滚,则必须抛出异常。