从应用程序服务层报告错误 [英] Reporting errors from the application services layer

查看:87
本文介绍了从应用程序服务层报告错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm implementing web application based on Spring MVC and organized around DDD concepts. Currently I try to implement ticket reservation functionality. The customer can see number of tickets available for the particular event. Then, he can enter number of tickets to be reserved and submit form. Request is received by controller which calls application service responsible for registration. Application service logic is as follows:


  1. 验证传入参数:

    • 1A。检查具有给定ID的事件是否存在

    • 1B。检查可用票数是否允许预订

我对报告验证错误的正确方法有一些疑问,尤其是对于第1B点。门票数量不允许预订的情况并非罕见。客户可以在数据库中看到与当前票证数量不完全同步的票证数量(最终一致性)-其他人可以同时保留一些票证。

I have some doubts about the proper way for reporting validation errors - especially for point 1B. Situation when number of tickets does not allow for reservation is not something very unusual. Customer can see number of tickets that is not fully synchronized with current number of tickets in database (eventual consistency) - some other person could reserve some tickets in the meantime.

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

Initially I was thinking about reporting this problems by throwing some specific exceptions. However, I can think of couple of other problematic situations and having one exception for each on of them doesn't sound very well.

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

The other option I was considering was throwing one type of exception containing error code. However, I don't know how to handle this situation in Spring MVC properly.

解决此类问题的最佳做法是什么?您如何在MVC应用程序中处理它们?

What are the best practices for such problems? How do you deal with them in your MVC applications? Any advices greatly appreciated.

推荐答案

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

I think these are business constraint brokens that cannot be recovered.

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

My current solution is 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 
}

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

Any custom exception extends this one. I think this could avoid code like this:

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减少样板尝试捕获代码(但非常困难)。

You can use @ExceptionHandler to reduce boilerplate try-catch code if your Controller is well organized(but pretty difficult).

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

The other reason to use Excepton is that application service is often used to delimit transaction boundary. An exception has to be thrown if you want to rollback.

这篇关于从应用程序服务层报告错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆