【发布时间】:2020-04-17 06:29:10
【问题描述】:
我的要求是访问从第一个服务抛出的自定义异常及其在第二个服务中的正文内容
到目前为止,我已经尝试了 2 个方法,FallbackFactory 和 ErrorDecoder,其中只有 Fallback factory 对我有用。错误解码器没有从其他服务抛出的异常消息。这是我在另一个问题中找到的示例代码:
将有 2 种服务:库存服务和产品服务
库存服务
InventoryController.java
@RestController
@RequestMapping("/inventories")
public class InventoryController {
private final ProductServiceClient productService;
public InventoryController(ProductServiceClient productService) {
super();
this.productService = productService;
}
@GetMapping
public ResponseEntity<?> companyInfo() {
return productService.hello();
}
}
ProductServiceClient.java
@FeignClient(name = "product-service", url = "http://localhost:9100", fallbackFactory = ProductServiceClientFallback.class)
public interface ProductServiceClient {
@GetMapping("/products")
ResponseEntity<?> hello();
}
@Component
class ProductServiceClientFallback implements FallbackFactory<ProductServiceClient> {
@Override
public ProductServiceClient create(Throwable cause) {
return new ProductServiceClient() {
@Override
public ResponseEntity<?> hello() {
System.out.println("hello!! fallback reason was " + cause.getMessage());
return ResponseEntity.ok().build();
}
};
}
}
产品-服务
ProductController.java
@RestController
@RequestMapping(value = "/products")
public class ProductController {
@GetMapping
public String hello() throws Exception {
if (true) {
throw new Exception("Service B Exception...");
}
return "Hello World";
}
}
ProductControllerAdvice.java
@RestControllerAdvice
public class ProductControllerAdvice {
@ExceptionHandler
public ResponseEntity<?> handleException(Exception exception) {
return new ResponseEntity<>("Caused due to : " + exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
所以,当 /inventories api 在 Inventory 控制器中触发时,它会通过 Feign 客户端触发对产品服务的调用,在产品服务端,我会抛出一个带有消息的自定义异常,我必须在我的库存服务中访问该消息。
为了实现这一点,我已经实现了后备工厂,并且它在测试工作区中工作,因为我在库存服务的控制台中得到了这样的输出
hello!! fallback reason was status 500 reading ProductServiceClient#hello(); content:
Caused due to : Service B Exception...
但是,我的问题是,当我对正在开发的应用程序尝试类似的方法时,我没有收到异常消息,而是得到了这样的输出:
reached fallback on workflow side, reason: status 400 reading ProvisioningServiceProxy#executeOrderAction(Long,Long,String)
服务-A
TestServiceA.java
@FeignClient( url = "/executeOrder", fallbackFactory = TestServiceAFallback.class )
public interface TestServiceA extends Serializable{
@PostMapping( value = "order/{requestId}/order/{orderId}/{command}" )
public ResponseEntity<ProcessInstanceVariable> executeOrderAction( @PathVariable( name = "command" ) String command );
}
Service-B 引发自定义异常的位置
TestServiceBController.java
@PostMapping( value = /executeOrder )
public ResponseEntity<ProcessInstanceVariable> executeOrderAction( @PathVariable( value = "command" ) String command )
{ //switch code to check the command value and throw exception for one particular command
throw new ValidationException("validation exception from service B");
}
我也有一个建议,它处理验证异常,并且该类中有这样的方法
TestServiceBControllerAdvice.java
@ExceptionHandler( ValidationException.class )
public ResponseEntity<Object> handleValidationException( ValidationException ve )
{
return new ResponseEntity<>( ve.getMessage(), HttpStatus.BAD_REQUEST );
}
所以,我希望在 TestServiceA 端收到我从 TestServiceB 发送的消息,但我收到一条通用消息,显示在读取 API 时出现 BAD REQUEST。
我不确定除了下面的配置之外,TestServiceA 端是否需要任何额外的配置:
testServiceA.properties
feign.hystrix.enabled=true
让我知道我是否遗漏了任何东西,我已经通过 this documentation 并且在我看来,我已经按照应该发生的方式完成了实现,以获取从其他服务抛出的消息和异常主体。
【问题讨论】:
-
你能解决这个问题吗?如果是,请提及您是如何解决的?我也有类似的问题。
-
@VishalPatel 从那以后已经有一段时间了,我记得只实现了错误解码器,我能够在响应正文中获得异常消息
标签: java spring spring-boot feign