在服务编排场景中,如何处理没有检查异常的错误?

大多数编程语言没有检查异常(如C#和Kotlin)。

所以,我试图找到一个更好的方法来处理我的项目,而不使用检查的异常。

该项目使用Java,我们控制远程EJB的可能的验证错误。 像这样的东西:

lookupSomeRemoteEjb().createCustomer(/** lots of informations */); 

这个方法抛出了许多的验证异常,例如:

 DocumentoAlreadyExistsException(); InvalidNameException(); InvalidBirthDateException(); 

等等。

这种例外可能发生在不同级别的不同课程中。 像这样的例子:

 CustomerRemoteEjb.class // tell to the another system what error happened CustomerService.class //can throw some errors about customer PersonService.class // can throw some errors about person DocumentService.class // can throw some errors about document AddressService.class // can throw some errors about address 

一个API调用这个远程EJB并捕获每一个错误,把这个消息翻译成API用户(使用这个远程EJB)的好消息。

运行良好,但是对于每个调用,很多丑陋的try / catch代码是一团糟。

我猜想替代方法是使用带有ID错误的未经检查的异常,或者使用类似于Result对象的类似ID的验证错误。

但是这个解决方案在一个更复杂的代码(顺便提一句,monolyth系统)中不太适合,因为很多时候这些验证是由另一个服务调用的服务完成的。 这将是奇怪的深层服务返回异常(或结果对象)与ID到另一个服务,他们到达API。

我读了一些关于检查异常的备选方法的旧讨论 ,但是对于最佳选择没有任何结论。 我仍然赞同那里的评论:

我正在阅读上面的讨论,我仍然不知道例外是否有好处。

所以,在类似的情况下,我怎样才能解决这个问题与不支持检查异常的语言?

使用不同的被检查的异常有一个基本的问题:它引入了版本兼容性问题。 如果双方可以有不同的代码级别,你必须担心使用“新”异常的ejb方面…

你的问题提供了一个潜在的解决方案(通过使用一些返回对象) 但是还有另一种选择:不要有不同的例外,你可以去一个例外。 那个异常带有某种错误ID。

含义:用户错误消息不是从异常类型派生的,而是从一些数字ID例如。 当然,这种方法还有其他的缺点 – 但是它仍然可以解决使用“每个问题一个异常类”方法时遇到的问题。

对于检查异常,只能使用一个泛型SystemException 。 这将解决“多重例外”问题。

但是, SystemException需要有关于异常的信息,如集成的错误代码和/或消息(如远程EJB)使用它们。

遗产代码,我会建议:

  • 打开所有LegacySpecificException扩展SystemException (或)

  • 将所有LegacySpecificException转换为SystemException

另一个问题:如果您需要“尝试捕获”另一个异常,而不是SystemException (例如, EJBException ),则需要处理该异常并重新引发SystemException

 } catch (EJBException e) { throw new SystemException(e.getMessage(), e); } 

* ref: https : //northconcepts.com/blog/2013/01/18/6-tips-to-improve-your-exception-handling/

对于您列出的例外类型:

  • DocumentoAlreadyExistsException();
  • InvalidNameException();
  • InvalidBirthDateException();

您可以编写验证方法来验证输入并返回验证数据值对象。 这个验证方法和数据值对象将随着应用程序的发展而变化,验证的复杂性被封装在这个方法中,并且可能存在于它自己的类中(并且可能会调用其他类来完成其他特定的任务)。

然后你可以做一些选择。

您可以创建一个具有验证数据值对象作为实例变量的Exception类ValidationException。 在原始方法的开始处调用验证方法,使用验证数据值对象作为实例变量创建并抛出验证异常类的实例。

您可以在调用原始方法之前调用验证方法,如果验证失败,则不要调用原始方法。

都。