【问题标题】:Modelling exceptions & Handling http codes inside a server application在服务器应用程序中建模异常和处理 http 代码
【发布时间】:2020-08-29 11:54:12
【问题描述】:

我正在开发一个 spring boot 应用程序,它对多个外部服务进行 http 调用,聚合并将响应返回给前端。

这是我项目的当前结构:

RouteController -> Handler -> ServiceLayer
  • RouteController 路由到不同的处理程序
  • Handler 调用多个服务,执行聚合并返回响应。
  • 每个服务调用都有不同的 ServiceLayers。
  • 处理程序可以返回部分响应,如果一个服务调用失败,它将返回其他调用的响应。
  • 我没有添加类/控制器级别的异常处理程序,因为也可以返回部分响应。

注意 - 此应用程序将始终发送 Http 200 响应,除非所有服务调用均失败。
Spring 异常处理https://www.baeldung.com/exception-handling-for-rest-with-spring 用于类/控制器级别,并将 Http 响应代码传送给客户端。 我在这里寻找的是应用程序内部的异常处理。

我正在尝试在此服务中添加异常处理,似乎没有明确简洁的规则。

这是我为任何依赖失败创建的自定义异常 -

class DependencyException : RuntimeException {
    constructor() : super()
    constructor(message: String?) : super(message)
    constructor(cause: Exception?) : super(cause)
    constructor(message: String?, cause: Exception?) : super(message, cause)
}

这是服务层调用 UserService 的代码 -

fun getUsers(): List<User>? {
        logger.info { "entered: getUsers " }
        val response = userControllerApiClient.getUsers()

        when (response.statusCode.is2xxSuccessful) {
            true -> return response.body?.users
            false ->  throw DependencyException()
        }
    }

已使用 org.springframework.http 库进行 http 调用。

有几个问题我找不到明确的答案-

  • 服务何时应编写自己的异常?
  • 何时使用 kotlin/java 标准库存在异常?
  • 是否应该将 spring http 异常传播到处理程序/控制器层?
  • 上面的依赖异常范围是不是太大了?
  • 是否应该将 4xx、5xx 错误代码转换为不同的自定义异常以进行内部处理? (还有每个系列对不同代码的不同处理?)
  • 您建议在此项目中处理异常的最佳方法是什么?

【问题讨论】:

标签: java spring-boot kotlin exception exceptionhandler


【解决方案1】:
  1. 服务何时应编写自己的异常? 当标准库中的现有异常未涵盖您的用例时,或者当您想在异常中添加更多详细信息时。

  2. 何时使用 kotlin/java 标准库存在的异常? 同上,不要试图重新发明轮子。就像,使用 IllegalArgumentException 而不是创建自己的 InvalidRequestException 。看看这里 - https://programming.guide/java/list-of-java-exceptions.html

  3. 是否应该将 spring Http 异常传播到处理程序/控制器层? 我建议不要将任何外部框架的异常传播到您的控制器。相反,编写您自己的异常,并尽可能多地使用 Java.lang 中的现有异常。 Http 异常应该保留在它们的预期位置,即请求/响应层。
  4. 上面的依赖异常范围是不是太大了? 这里的依赖异常太宽泛了,如果你的应用程序必须以不同的方式处理不同的 Http 代码怎么办。你将如何处理?
  5. 4xx,5xx错误码是否应该转换成不同的自定义异常类型? (还有每个系列对不同代码的不同处理?) 很大程度上取决于客户想要什么。正如您所提到的,在您的情况下,您正在编排层处理它们并抑制它们。您是否认为这种实现在未来会发生变化,以及变化多远? 我建议的第一步是至少将 4xx 和 5xx 错误映射到不同的异常。仔细看看,看看你想重试/恢复哪些类型,并从中派生另一种类型。

这里有一些资源我认为你应该看看 -

https://itnext.io/graceful-error-handling-in-rest-driven-web-applications-d4209b4937aa

https://github.com/cloudendpoints/endpoints-java/blob/master/endpoints-framework/src/main/java/com/google/api/server/spi/ServiceException.java

REST API error return good practices

【讨论】:

    【解决方案2】:

    您好:

    1. 服务何时应该编写自己的异常? -->

    这取决于您的业务逻辑,例如您有一个服务层 更新用户,如果用户没有找到你,你应该通过 ID 找到它 应该抛出异常

    1. 何时使用 kotlin/java 标准库存在的异常?

    如果你使用spring-boot是一个框架为你提供准备 libs 和 APIS 来处理所有你可以检查这个链接 https://www.baeldung.com/exception-handling-for-rest-with-spring

    1. 是否应该将 spring Http 异常传播到处理程序/控制器 层?

    是的;因为控制器负责处理 Http 例外,业务层的服务

    1. 上面的依赖异常范围是不是太大了?

    这个问题我没看懂

    1. 4xx,5xx错误码是否应该转换成不同的自定义 异常类型? (以及对不同代码的不同处理 每个系列? )

    不需要,建议返回Http错误码和自定义消息,以便客户端了解异常错误原因

    1. 您推荐的处理异常的最佳方法是什么 项目?

    我推荐遵循 jhiptser spring boot 项目结构,https://www.jhipster.tech/managing-server-errors/

    【讨论】:

    • Spring 异常处理 baeldung.com/exception-handling-for-rest-with-spring 用于类/控制器级别,并将适当的 http 响应代码传达给客户端。我在这里寻找的是应用程序内部的异常处理。此应用程序将始终发送带有部分响应的 Http 200 响应。
    • 应用程序内部是什么意思?您的应用程序由一系列组件组成,如控制器、服务和存储库,每个组件都有自己的角色,您能解释一下吗?
    • 所以有一个基本控制器 -> 处理程序 -> 服务。 handler 调用多个服务并聚合数据,并始终向 basecontroller 返回成功。我们将抑制来自任何服务的异常,以便发送来自其他服务调用的响应。
    猜你喜欢
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    相关资源
    最近更新 更多