是否应该从应用程序层抛出域异常? [英] Should my Domain Exceptions be thrown from Application Layer?

查看:107
本文介绍了是否应该从应用程序层抛出域异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读沃恩·弗农(Vaughn Vernon)的书-实施域驱动设计。有一个项目管理应用程序的示例。有聚合,例如BacklogItem,Sprint等。如果我在Domain层中定义了BacklogItemNotFoundException。我的Rest适配器应该抓住它并转换为NotFoundHttpResult吗?还是任何其他破碎的不变异常,例如:EmailPatternBrokenException或TooManyCharactersForNameException或应在Rest适配器(端口和适配器体系结构)中处理的任何东西,然后重新转换为Rest响应?如果是,这意味着RestAdapter应该具有对Domain层的引用?这就是困扰我的地方……

I'm reading Vaughn Vernon Book - Implementing Domain Driven Design. There is an example of a Project Management Application. There are aggregates like BacklogItem, Sprint, etc. If I have BacklogItemNotFoundException defined in Domain layer. Should my Rest adapter catch it and transform into NotFoundHttpResult? Or any other broken invariant exceptions like: EmailPatternBrokenException or TooManyCharactersForNameException or whatever should be handled in Rest adapter(ports&adapters architecture) and re-transformed into rest responses? If yes, it means that RestAdapter should have a reference to Domain layer? This is what bothers me...

推荐答案

问题是矛盾的。如果是域异常,则意味着它是由域引发的。

The question is a contradiction. If it is a Domain Exception, it means that it is thrown by the domain.

无论如何,域引发的异常应由应用程序层处理。

Anyway, exceptions thrown by the domain should be handled by the application layer.

我有一个用于命令总线的异常处理程序装饰器,可以捕获任何域异常并将其转换为应用程序异常。

I have an exception handler decorator for the command bus, that catch any domain exception and translates it into an Application Exception.

此应用程序异常被抛出到适配器。

This application exception is thrown to the adapters.

适配器知道应用程序异常,而不是域异常。

Adapters know about application exceptions, not domain exceptions.

更新

我的域异常是抽象的基类,具体的域异常从中继承

My domain exception is an abstract base class from which the concrte domain exceptions inherit

public abstract class DomainException extends RuntimeException {

private static final long serialVersionUID = 1L;

private ErrorMessage mainErrorMessage;
private List<ErrorMessage> detailErrorMessages;

protected DomainException ( List<ErrorMessage> aDetailMessages, Object... aMainMessageArgs ) {
    this.mainErrorMessage = new ErrorMessage(this.getClass().getSimpleName(), aMainMessageArgs );
    this.detailErrorMessages = ( (aDetailMessages==null) ? new ArrayList<ErrorMessage>() : aDetailMessages );
}

public ErrorMessage mainErrorMessage() {
    return this.mainErrorMessage;
}

public List<ErrorMessage> detailErrorMessages() {
    return this.detailErrorMessages;
}
}

ErrorMessage有一个键和一个参数列表。消息位于属性文件中,其中的键是具体域异常类的名称。

ErrorMessage has a key and a list of args. The messages are in a property file where the key is the name of the concrete domain exception class.

应用程序异常只是其中一种类型,其中包含具体的文本消息。 / p>

Application exception is just one type, which holds the concrete text message.

public class ApplicationException extends Exception {

private static final long serialVersionUID = 1L;


private String mainMessage;
private String[] detailMessages = new String[0];


public ApplicationException ( String aMainMessage, Throwable aCause, String... aDetailMessages ) {
    super ("Main Message = "+aMainMessage+" - DetailMessages = "+Utils.toString(aDetailMessages), aCause );
    this.mainMessage = aMainMessage;
    this.detailMessages = ( (aDetailMessages==null) ? (new String[0]) : aDetailMessages );
}


public String mainMessage() {
    return this.mainMessage;
}

public boolean hasDetailMessages() {
    return (this.detailMessages.length > 0);
}

public String[] detailMessages() {
    return this.detailMessages;
}
}

我有一个装饰器(包装每个命令的执行)处理域异常:

I have a decorator (wraps the execution of every command) for handling domain exceptions:

public class DomainExceptionHandlerDecorator extends Decorator {

private final DomainExceptionHandler domainExceptionHandler;


public DomainExceptionHandlerDecorator (DomainExceptionHandler domainExceptionHandler) {
    this.domainExceptionHandler = domainExceptionHandler;
}


@Override
public <C extends Command> void decorateCommand(Mediator mediator, C command) throws ApplicationException {
    try {
        mediator.executeCommand(command);
    } catch ( DomainException de ) {
        this.domainExceptionHandler.handle (de);
    }
}
}

我有一个域例外接受域异常的处理程序,通过读取属性文件将其转换为应用程序异常(TextMessageService完成该工作),并引发应用程序异常。

And I have a domain exception handler that takes a domain exception, translates it into an app exception by reading properties file (TextMessageService does the job) and throw the app exception.

public class TranslatorDomainExceptionHandler implements DomainExceptionHandler {

private final TextMessageService configurationService;

public TranslatorDomainExceptionHandler ( TextMessageService aConfigurationService ) {
    this.configurationService = aConfigurationService;
}

@Override
public void handle ( DomainException de ) throws ApplicationException {

    ErrorMessage mainErrorMessage = de.mainErrorMessage();
    List<ErrorMessage> detailErrorMessages = de.detailErrorMessages();

    String mainMessage = this.configurationService.mensajeDeError ( mainErrorMessage );

    String[] detailMessages = new String [ detailErrorMessages.size() ];

    int i = 0;
    for ( ErrorMessage aDetailErrorMessage : detailErrorMessages ) {
        detailMessages[i] = this.configurationService.mensajeDeError ( aDetailErrorMessage );
        i++;
    }
    throw new ApplicationException ( mainMessage, de, detailMessages);      
}
}

适配器(例如UI)将捕获应用异常并向用户显示其消息。但是它不知道域例外。

The adapter (an UI for example) will catch the app exception and show its message to the user. But it doesn't know about domain exceptions.

这篇关于是否应该从应用程序层抛出域异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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