如何取消在带有消息的深度调用堆栈中的处理?
How do I cancel processing in a deep call stack with messages?
我的要求是用户将在流程结束时看到本地化消息。如果进程失败,将至少有一条错误类型的“外部”消息。如果进程成功执行,用户可能会看到多个“外部”信息消息。
此外,应用程序应记录所有消息(包括内部消息)。
棘手的部分来了。假设以下调用堆栈:
- controller.uploadImageHandler
- imageService.createImageContainer
- galleryService.loadForImage
- galleryService.validateGalleryAttributes
现在 validateGalleryAttributes
将验证 3 个属性。 2 不匹配,因此生成 External
类型的消息 Attribute A must be X
和 Attribute B must not be empty
并记录到应用程序日志中。之前的调用添加了多条信息消息。
现在我需要
- 中止处理
- 将消息冒泡
将消息集合(或将集合添加到记录器)传递到每个方法中,在失败时抛出异常(即使是简单的异常,例如无效属性),在控制器级别提取消息是正确的方法return 给用户?将它们添加到异常 class 是不够的,因为信息消息也必须是可能的,并且多个方法可能只产生消息。
但老实说,拥有一个在成功和异常时进行检查的集合似乎有点奇怪。有没有更好的语言结构?
我可以想出两个替代解决方案。
如果你对 monad 很感兴趣,你可以从使用异常转向自定义 LoggingEither<L, R>
或 LoggingResult<S, E>
return 类型。他们将携带 result/exception 以及迄今为止所有累积的消息。您只需确保将调用的所有方法的消息合并到当前方法中 return 的对象中。有关如何实现这些 monad 类型的想法,请查看 vavr.
如果所有事情都发生在同一个线程中,您可以考虑使用 ThreadLocal 来跟踪所有日志消息。这消除了将集合向下传递到堆栈跟踪的需要。不过,您仍然需要注意捆绑消息和重置 ThreadLocal
。
我的要求是用户将在流程结束时看到本地化消息。如果进程失败,将至少有一条错误类型的“外部”消息。如果进程成功执行,用户可能会看到多个“外部”信息消息。
此外,应用程序应记录所有消息(包括内部消息)。
棘手的部分来了。假设以下调用堆栈:
- controller.uploadImageHandler
- imageService.createImageContainer
- galleryService.loadForImage
- galleryService.validateGalleryAttributes
现在 validateGalleryAttributes
将验证 3 个属性。 2 不匹配,因此生成 External
类型的消息 Attribute A must be X
和 Attribute B must not be empty
并记录到应用程序日志中。之前的调用添加了多条信息消息。
现在我需要
- 中止处理
- 将消息冒泡
将消息集合(或将集合添加到记录器)传递到每个方法中,在失败时抛出异常(即使是简单的异常,例如无效属性),在控制器级别提取消息是正确的方法return 给用户?将它们添加到异常 class 是不够的,因为信息消息也必须是可能的,并且多个方法可能只产生消息。
但老实说,拥有一个在成功和异常时进行检查的集合似乎有点奇怪。有没有更好的语言结构?
我可以想出两个替代解决方案。
如果你对 monad 很感兴趣,你可以从使用异常转向自定义
LoggingEither<L, R>
或LoggingResult<S, E>
return 类型。他们将携带 result/exception 以及迄今为止所有累积的消息。您只需确保将调用的所有方法的消息合并到当前方法中 return 的对象中。有关如何实现这些 monad 类型的想法,请查看 vavr.如果所有事情都发生在同一个线程中,您可以考虑使用 ThreadLocal 来跟踪所有日志消息。这消除了将集合向下传递到堆栈跟踪的需要。不过,您仍然需要注意捆绑消息和重置
ThreadLocal
。