我们有一个基于微服务的体系结构,该体系结构包含主应用程序服务器模块和libs模块。 在主应用服务器中,我们仅接受请求并通过REST API方法上的请求和响应对象提供响应,这些方法调用libs模块中可用的服务层。
parent--
------apps
---server
---Controller Class
------libs
---core
---Service Layer
---Dao Layer
要传播错误消息以便可以使用Response Object(仅在Controller类中提供)将其发送到客户端,我们在服务层中抛出自定义异常,以便可以将错误消息发送到Controller类。 这种方法的问题是,在所有情况下都将引发异常,例如,即使输入不正确或用户没有权限,我们也会引发异常,在这种情况下,我们可以仅向用户返回错误消息。
我的问题是-仅出于将错误消息从Service层传播到Controller的目的而抛出Custom异常是否正确? 如果否,那么我们如何将错误消息传播到控制器层?
服务层---
public String serviceLayerMethod(String param) throws AssetException {
try {
if(param==null){
throw new CustomException;
} else{
return param;
}
} catch (CustomException e) {
LOGGER.error(CustomExceptionEnum.PARAMNULL_EXCEPTION.getMessage(),e);
throw new CustomException(CustomExceptionEnum.PARAMNULL_EXCEPTION.getMessage(), e);
}
}
控制器层---
public Response restAPI(Request request) {
try {
response.setMessage(service.serviceLayerMethod());
response.setSuccess(true);
} catch (CustomException e) {
response.setMessage(e.getMessage());
response.setSuccess(false);
}
return response
}
答案 0 :(得分:2)
我看不到有任何问题,但是使用Spring在Rest API上为您做的更好。
在Spring上,您可以使用@RestControllerAdvice
和@ExceptionHandler
来捕获任何异常并为用户返回一个不错的消息。喜欢:
@Slf4j
@RestControllerAdvice
public class ErrorHandlerController {
@ExceptionHandler(CustomException.class)
public ResponseEntity<ApiErrorResponse> handleApiException(CustomException ex, Locale locale) {
log.error("Custom error catch with the code {}", ex.getErrorCode(), ex);
ApiErrorResponse error = new ApiErrorResponse(ex, locale);
return new ResponseEntity<>(error, ex.getHttpStatus());
}
}
答案 1 :(得分:1)
正如内维尔指出的那样;这是一个值得商topic的话题,没有什么是对与错。
我的观点是API应该独立于UI。因此,如果异常引发异常,则可以将其抛出。并让客户端处理该异常或决定如何处理该异常。一些客户可能想显示一条优美的用户友好消息;其他客户端可能想要实际的消息(例如,如果另一个算法正在调用此API)。
答案 2 :(得分:0)
我认为记录该错误并仅将HTTP错误显示为该错误是有意义的,例如BAD_REQUEST或INTERNAL_SERVER_ERROR ...
答案 3 :(得分:0)
这是complex and subtle topic-可能基于意见。
首先,避免使用异常来传达应用程序逻辑。您的示例并不暗示您正在执行此操作,但通常使用自定义异常来传达应用程序或域逻辑,并且在try / catch块中对其进行处理很难读取,难以测试且难以发展。例如,如果由于客户超出了信用额度(业务规则)而导致购买失败,那么我将避免使用自定义例外来管理该实例。
第二,尝试使用内置异常,而不是创建自己的异常。 Java有几个内置的参数验证实例。复制它们不会增加任何价值。仅在找不到内置Java异常时才创建自定义异常。
第三,如果可以的话,尝试在控制器层中处理应用程序异常-将所有内容下推到服务层中会使该层变得更加复杂且难以测试。
最后,重点关注如何将错误传达给客户端-常见的模式是使用HTTP错误代码。最终,您可能最终将自定义异常转换为“ HTTP:500”代码,并且希望您的客户端应用程序能够以一致的方式推理这些异常。