AWS Lambda平台Spring Cloud功能中的全局异常处理



我在AWS lambda上使用spring云功能。我正试图使用@ExceptionHandler注释实现像Spring Boot这样的全局异常处理。但是这个方法没有被执行任何类型的异常我都得到了500。
示例代码如下-

@SpringBootApplication
public class App{
public static void main( String[] args ){
SpringApplication.run(App.class, args);
}
@Bean
public Function<Message<User>, User> getUser(){
return (message)->{
User u = message.getPayload();
if(u==null){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,"No user details provided");
} 
return u;
}
}
@ExceptionHandler(ResponseStatusException.class)
public APIGatewayProxyResponseEvent handleException(ResponseStatusException e){
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
response.setStatusCode(e.getRawStatusCode());
response.setBody(e.getMessage());
return response;
}
}

我得到500响应而不是错误的请求. 有什么方法可以实现这个场景吗?

您可以在构建SpringBootLambdaContainerHandler时提供您的自定义exceptionHandler。

public class StreamLambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
handler = new SpringBootProxyHandlerBuilder<AwsProxyRequest>()
.defaultProxy()
.exceptionHandler(***your customer handler here***)
// other methods are skipped
.buildAndInitialize();  
}
}

如果你正在使用spring云函数,不需要使用SpringBootLambdaContainerHandler,你需要做的是创建一个自定义路由函数,处理从lambda函数抛出的异常,并返回APIGatewayProxyResponseEvent。下面显示了我是如何获得预期结果的

public class CustomRoutingFunction implements Function<Message<?>, APIGatewayProxyResponseEvent> {
private final FunctionCatalog functionCatalog;
private final FunctionProperties functionProperties;
private final MessageRoutingCallback routingCallback;
public static final String DEFAULT_ROUTE_HANDLER = "defaultMessageRoutingHandler";

public CustomRoutingFunction(FunctionCatalog functionCatalog,
FunctionProperties functionProperties,
MessageRoutingCallback routingCallback) {
this.functionCatalog = functionCatalog;
this.functionProperties = functionProperties;
this.routingCallback = routingCallback;
}
@Override
public APIGatewayProxyResponseEvent apply(Message<?> input) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
try {
String functionDefinition = this.routingCallback.routingResult(input);
SimpleFunctionRegistry.FunctionInvocationWrapper function = functionCatalog.lookup(functionDefinition);
Object output = function.apply(input);
String payload = mapper.writeValueAsString(output);
return new APIGatewayProxyResponseEvent()
.withIsBase64Encoded(false)
.withBody(payload)
.withHeaders(Map.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE,
"statusCode", "200"))
.withStatusCode(200);
} catch (Exception e) {
return new APIGatewayProxyResponseEvent()
.withIsBase64Encoded(false)
.withHeaders(Map.of(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON_VALUE,
"statusCode", String.valueOf(HttpStatus.BAD_REQUEST.value())))
.withBody(e.getMessage())
.withStatusCode(HttpStatus.BAD_REQUEST.value());
}
}
}

现在你需要将路由器功能注册为bean并将其传递给spring.cloud.function.definition

@Bean
public CustomRoutingFunction customRoutingFunction(FunctionCatalog functionCatalog,
FunctionProperties functionProperties,
@Nullable MessageRoutingCallback routingCallback,
@Nullable DefaultMessageRoutingHandler defaultMessageRoutingHandler) {
if (defaultMessageRoutingHandler != null) {
FunctionRegistration functionRegistration = new FunctionRegistration(defaultMessageRoutingHandler, CustomRoutingFunction.DEFAULT_ROUTE_HANDLER);
functionRegistration.type(FunctionTypeUtils.consumerType(ResolvableType.forClassWithGenerics(Message.class, Object.class).getType()));
((FunctionRegistry) functionCatalog).register(functionRegistration);
}
return new CustomRoutingFunction(functionCatalog, functionProperties, routingCallback);
}

在您的应用程序中。yml文件

spring:
cloud:
function:
definition: customRoutingFunction 

最新更新