简体   繁体   English

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

[英]Errorhandling between frontend and backend

at work we building an web application with java spring backend and vue frontend.在工作中,我们使用 java spring 后端和 vue 前端构建一个 web 应用程序。 At the moment we uses 2 or 3 http response code to pass errors between frontend and backend.目前我们使用 2 或 3 个 http 响应代码在前端和后端之间传递错误。 If you call and endpoint with wrong parameters, you'll get an BAD_REQUEST.如果您使用错误的参数调用和端点,您将收到 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.如果在后端抛出一些异常(与参数无关),后端返回一个 INTERNAL_SERVER_ERROR,如果你传递一些不在数据库中的 id,后端返回一个 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.我们想向用户指出问题,这些问题不能通过 HTTP 响应代码进行分类。 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...但我不知道“SERVICE_UNAVAILABLE”是否适合这里......

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).我已经找到了这个: https://www.baeldung.com/spring-response-status-exception我们可以使用消息字段传递有关错误的详细信息(消息字段中的特定错误 json)。 Is this a good idea?这是一个好主意吗?

Opinions?意见?

T

You can certainly pass information back in this field but using ResponseStatusException s.您当然可以在此字段中传回信息,但使用ResponseStatusException s。 Depending on how much information the frontend needs (eg 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 .如果您想在响应中使用自定义 object(尤其是每个异常/响应代码),另一种方法是使用@ControllerAdvice并扩展ResponseEntityExceptionHandler

eg say you have a custom exception ExternalServiceUnavailableException which had some underlying ServiceInformation you could retrieve from it.例如,假设您有一个自定义异常ExternalServiceUnavailableException ,它具有一些您可以从中检索的基础ServiceInformation 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当您抛出ExternalServiceUnavailableException时,这将导致响应正文如下

{
    "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.可以在下面的文章中找到更完整的示例,其中相同的自定义错误 object 用于后果的每个异常以及默认处理程序。

https://www.baeldung.com/exception-handling-for-rest-with-spring 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.编辑:值得记住的是,还有响应代码 502(网关错误)和 504(网关超时)可用于指示外部服务不可用或超时。 If these are appropriate you could just use appropriate ResponseStatusExceptions with a message set to include the service name (or other info).如果这些是合适的,您可以只使用适当的ResponseStatusExceptions和消息集以包含服务名称(或其他信息)。 As above, it depends on what you need/want the fronted to receive.如上所述,这取决于您需要/希望前台接收什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM