如何在服务编排方案中处理错误而不检查异常?



大多数编程语言都没有检查异常(如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)发送一条很好的消息。

效果很好,但代码很混乱,每次调用都有很多丑陋的尝试/捕获。

我想另一种方法是使用带有 ID 错误的未经检查的异常,或者使用具有相同类型 ID 的Result对象之类的东西来处理验证错误。

但是这种解决方案不太适合更复杂的代码(顺便说一下,单lyth系统),因为很多时候这些验证是由另一个服务调用的服务进行的。奇怪的是,这种深度服务在到达 API 之前将带有 ID 的异常(或结果对象)返回给另一个服务。

我读过一些关于检查异常替代方案的旧讨论,但没有关于最佳替代方案的结论。我仍然同意那里的评论:

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

那么,在类似的情况下,如何使用不支持检查异常的语言解决此问题?

使用不同的检查异常实际上有一个基本问题:它引入了版本兼容性问题。如果两端可以有不同的代码级别,你必须担心 ejb 端使用"较新"的异常......

您的问题给出了一个潜在的解决方案(通过使用一些返回对象)。但是还有另一种选择:与其有无数不同的例外 - 你可以选择单个例外。该异常带有某种错误 ID。

含义:例如,用户错误消息不是从异常类型派生的,而是从某个数字 id 派生的。当然,这种方法还有其他缺点 - 但它仍然解决了您在使用"每个问题一个异常类"方法时遇到的(一些)问题。

对于已检查的异常,只能使用一个通用的系统异常。这将解决"捕获多个异常"问题。

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

对于遗留代码,我建议:

  • 将所有LegacySpecificException扩展系统异常(或)

  • 将所有LegacySpecificException转换为SystemException

另一个问题:如果你需要"try-catch"另一个异常而不是SystemException(例如EJBException),你需要处理它并重新抛出SystemException

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

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

对于您列出的异常类型:

  • DocumentoAlreadyExistException();
  • 无效名称异常();
  • 无效出生日期异常();

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

然后,您可以执行多个选项之一。

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

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

双。

最新更新