前端和后端之间的错误处理

发布于 2025-01-11 04:56:50 字数 628 浏览 0 评论 0原文

在工作中,我们使用 java spring 后端和 vue 前端构建一个 Web 应用程序。 目前我们使用 2 或 3 个 http 响应代码在前端和后端之间传递错误。 如果您使用错误的参数调用和端点,您将收到 BAD_REQUEST。如果后端抛出一些异常(与参数无关),后端将返回 INTERNAL_SERVER_ERROR,如果您传递一些不在数据库中的 id,后端将返回 NOT_FOUND。

这种方法有多个问题:

  • 在错误情况下我们没有结构可以用来将信息传递给用户(前端),
  • 我们想要向用户指示问题,而这些问题无法通过 HTTP 响应代码进行分类。例如,如果外部服务不可用,我们希望将服务名称传递给前端。但我不知道“SERVICE_UNAVAILABLE”是否适合这里......

我已经发现了: https://www.baeldung.com/spring-response-status-exception 我们可以使用消息字段来传递有关错误的详细信息(消息字段中的特定错误 json)。 这是个好主意吗?

意见?

时间

at work we building an web application with java spring backend and vue frontend.
At the moment we uses 2 or 3 http response code to pass errors between frontend and backend.
If you call and endpoint with wrong parameters, you'll get an BAD_REQUEST. If some exception was thrown in the backend (which isn't related with the parameters) the backend returns an INTERNAL_SERVER_ERROR and if you pass some ids which aren't in the database the backend returns an NOT_FOUND.

This method has multiple problems:

  • we have no structure in error case which we can use to pass information to the user (frontend)
  • we want to indicate problems to the user, which can't be classified by HTTP response codes. For example if an external service isn't available, we want to pass the service name to the frontend. But I don't know if "SERVICE_UNAVAILABLE" fits here...

I found this already: https://www.baeldung.com/spring-response-status-exception
We could use the message field to pass detailed information about an error (specific error json in message field).
Is this a good idea?

Opinions?

T

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

断舍离 2025-01-18 04:56:50

您当然可以在此字段中传回信息,但使用 ResponseStatusException 。根据前端需要多少信息(例如,如果它只是向用户显示用户友好的消息),这可能足以满足您的需求。

如果您想在响应中使用自定义对象(尤其是每个异常/响应代码),另一种方法是使用 @ControllerAdvice 并扩展 ResponseEntityExceptionHandler。

例如,假设您有一个自定义异常 ExternalServiceUnavailableException,它具有一些您可以从中检索的底层 ServiceInformation。然后您可以执行类似

public class ServiceInformation {
    private final String name;
    private final String status;
    private final String statusMessage;

//snip
}

@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler({ ExternalServiceUnavailableException.class })
    public ResponseEntity<Object> handleExternalServiceUnavailable(ExternalServiceUnavailableException ex, WebRequest request) {

        final ServiceInformation si = ex.getServiceInformation();
        return ResponseEntity
            .status(503) // or whatever code you want
            .body(si); // or map to some other object/format
        // or use the constructor to supply headers etc.
    }
}

当您抛出 ExternalServiceUnavailableException 时的操作,这将导致类似的响应正文。

{
    "name": "my-external-service",
    "status": "timeout",
    "statusMessage": "Service timed out after 30 seconds"
}

更完整的示例可以在下面的文章中找到,其中每个错误使用相同的自定义错误对象结果异常以及默认处理程序。

https://www.baeldung.com/exception-handling-for- rest-with-spring

这使得前端更容易解释(就像您提出的方法一样),因为只有一种格式可以预期和解析,但您可以自由地为每个异常返回不同的响应形状。

编辑:值得记住的是,还有响应代码 502(错误网关)和 504(网关超时),可用于指示外部服务不可用或超时。如果这些是合适的,您可以使用适当的 ResponseStatusExceptions 和消息集来包含服务名称(或其他信息)。如上所述,这取决于您需要/希望前端收到什么。

You can certainly pass information back in this field but using ResponseStatusExceptions. Depending on how much information the frontend needs (e.g. if it's just surfacing a user friendly message to the user) this may be enough for your needs.

Another approach, if you want to use a custom object in the response (esp. per exception/response code), is using @ControllerAdvice and extending ResponseEntityExceptionHandler.

e.g. say you have a custom exception ExternalServiceUnavailableException which had some underlying ServiceInformation you could retrieve from it. Then you could do something like

public class ServiceInformation {
    private final String name;
    private final String status;
    private final String statusMessage;

//snip
}

@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler({ ExternalServiceUnavailableException.class })
    public ResponseEntity<Object> handleExternalServiceUnavailable(ExternalServiceUnavailableException ex, WebRequest request) {

        final ServiceInformation si = ex.getServiceInformation();
        return ResponseEntity
            .status(503) // or whatever code you want
            .body(si); // or map to some other object/format
        // or use the constructor to supply headers etc.
    }
}

When you throw a ExternalServiceUnavailableException this would result in a response body like

{
    "name": "my-external-service",
    "status": "timeout",
    "statusMessage": "Service timed out after 30 seconds"
}

A more complete example of this can be found in the below article where the same custom error object is used for each of the exceptions of consequence as well as a default handler.

https://www.baeldung.com/exception-handling-for-rest-with-spring

This makes it easier for the frontend to interpret (as does your proposed approach) since there is only a single format to expect and parse, but you are free to return different response shapes per exception.

Edit: it's worth remembering that there are also response codes 502 (bad gateway) and 504 (gateway timeout) which can be used to indicate an external service is either unavailable or timing out. If these are appropriate you could just use appropriate ResponseStatusExceptions with a message set to include the service name (or other info). As above, it depends on what you need/want the fronted to receive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文