使用Spring Boot和Kotlin进行基于环境的错误处理

Providing simple but meaningful messages while handling errors in web services should be the preferred approach. This way, we will not expose any internal information about the causes of the errors and we will help the API client properly respond to issues.

在处理Web服务中的错误时提供简单但有意义的消息应该是首选方法。 这样,我们将不会暴露有关错误原因的任何内部信息,并且我们将帮助API客户端正确响应问题。

When an error occurs, the default Spring Boot behavior is to return a stack trace. The main downside of this approach is that it might leak useful information about our implementation to a potential attacker. On the other hand, stack traces — unlike meaningful messages — are extremely important for debugging.

发生错误时,默认的Spring Boot行为是返回堆栈跟踪。 这种方法的主要缺点是可能会将有关我们实施的有用信息泄露给潜在的攻击者。 另一方面,与有意义的消息不同,堆栈跟踪对于调试非常重要。

“Stack traces can tell the developer more about the sequence of events that led to a failure, as opposed to merely the final state of the software when the error occurred. Unfortunately, the same information can be useful to an attacker. The sequence of class names in a stack trace can reveal the structure of the application as well as any internal components it relies on.” — Semmle

“堆栈跟踪可以告诉开发人员更多有关导致失败的事件顺序的信息,而不只是错误发生时软件的最终状态。 不幸的是,相同的信息可能对攻击者有用。 堆栈跟踪中的类名顺序可以揭示应用程序的结构及其依赖的任何内部组件。” —西姆勒

The main goal of the approach we are going to present is to automatically adapt error messages according to the current deployment environment. In the staging environment, a simple and meaningful message, as well as a stack trace, will be returned. In the production environment, we will expose only the first one.

我们将要介绍的方法的主要目标是根据当前的部署环境自动调整错误消息。 在登台环境中,将返回一条简单而有意义的消息以及堆栈跟踪。 在生产环境中,我们将仅公开第一个。

Let’s see how this can be achieved in Spring Boot and Kotlin.

让我们看看如何在Spring BootKotlin中实现这一点。

处理不同的部署环境 (Handling Different Deployment Environments)

To understand which deployment environment we are in, we will use a custom environment variable called ENV. We assume that its value is PRODUCTION in the production environment and STAGING in the staging environment. In Kotlin, environment variables value can be retrieved as follows:

为了了解我们所处的部署环境,我们将使用一个名为ENV的自定义环境变量。 我们假设其值为PRODUCTION 在生产环境和STAGING 在暂存环境中。 在Kotlin中,可以按以下方式检索环境变量值:

System.getenv("env_name")

定义自定义错误类 (Defining a Custom Error Class)

We are going to define a custom class called ErrorMessage to represent API errors. The goal of this class is to wrap exceptions in a nice JSON representation to make life easier for API clients.

我们将定义一个名为ErrorMessage的自定义类来表示API错误。 此类的目标是将异常包装在漂亮的JSON表示中,以简化API客户端的工作。

We can implement such a class as follows:

我们可以实现这样的类,如下所示:

As you can notice, the stackTrace attribute is nullable and optional since it will be used in the staging environment only.

如您stackTracestackTrace属性是可空的并且是可选的,因为它将仅在登台环境中使用。

基于Spring Boot环境的错误处理 (Spring Boot Environment-Based Error Handling)

Using @ExceptionHandler and @ControllerAdvice is one of the main methods to handle errors since Spring Boot 3.2.

从Spring Boot 3.2 @ExceptionHandler ,使用@ExceptionHandler@ControllerAdvice是处理错误的主要方法之一。

@ExceptionHandler is a Spring annotation that provides a mechanism to treat exceptions that are thrown during execution of handlers (Controller operations). This annotation, if used on methods of controller classes, will serve as the entry point for handling exceptions thrown within this controller only. Altogether, the most common way is to use @ExceptionHandler on methods of @ControllerAdvice classes so that the exception handling will be applied globally or to a subset of controllers.” — Toptal

@ExceptionHandler是Spring注释,它提供一种机制来处理在执行处理程序(控制器操作)期间引发的异常。 如果在控制器类的方法上使用此注释,它将仅用作处理在此控制器内引发的异常的入口。 总之,最常见的方法是在@ControllerAdvice类的方法上使用@ExceptionHandler ,以便将异常处理应用于全局或应用于控制器的子集。” —托塔尔

Thanks to them, we can build a global error handling component called ControllerExceptionHandler. Its goal is to catch exceptions and wrap them in ErrorMessage objects, which will be serialized into JSON and sent back to API clients. It also implements the environment-based logic, as shown below:

多亏了他们,我们可以构建一个名为ControllerExceptionHandler的全局错误处理组件。 其目标是捕获异常并将它们包装在ErrorMessage对象中,该对象将序列化为JSON并发送回API客户端。 它还实现了基于环境的逻辑,如下所示:

The most important method is generateResponse, which converts the exception stack trace to a String (as described in this course) and passes it to the ErrorResponse constructor only when not in the production environment.

最重要的方法是generateResponse ,它将异常堆栈跟踪转换为String(如本课程所述),仅在生产环境中不使用时,才将其传递给ErrorResponse构造函数。

Example of the same error response in the production and staging environment, respectively.
分别在生产和登台环境中相同错误响应的示例。

This way, the message attribute can be used to explain what happened to users. In the staging environment, developers can understand why the error occurred thanks to the stackTrace attribute.

这样, message属性可用于解释用户发生了什么。 在登台环境中,开发人员可以通过stackTrace属性来理解为什么会发生错误。

额外 (Extra)

This tutorial can be used to build a custom error-handling layer to add to the multi-layered architecture we presented in this article.

本教程可用于构建自定义的错误处理层,以添加到本文中介绍的多层体系结构中。

结论 (Conclusion)

Not being able to understand why an error occurred can be frustrating! Exposing detailed error descriptions can be dangerous. There is a way to cautiously face this issue, however. Using the approach above, when an error occurs, users will always see a simple message. But when in the staging environment, developers will have everything they need to debug it.

无法理解为什么会发生错误可能令人沮丧! 公开详细的错误描述可能很危险。 但是,有一种方法可以谨慎地面对这个问题。 使用上述方法,当发生错误时,用户将始终看到一条简单的消息。 但是,在暂存环境中,开发人员将拥有调试所需的一切。

That’s all, folks! I hope this helps you handle errors in Spring Boot and Kotlin. Let me know if you have any comments or suggestions.

就是这样,伙计们! 我希望这可以帮助您处理Spring Boot和Kotlin中的错误。 如果您有任何意见或建议,请告诉我。

翻译自: https://medium.com/better-programming/environment-based-error-handling-with-spring-boot-and-kotlin-b36b901135ad

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值