如何在API Gateway响应映射中用正则捕获组提取Lambda异常数据
问题:Lambda异常数据映射到API Gateway响应失败
最近我在做Lambda和API Gateway集成的时候,碰到个头疼的问题——想把Lambda抛出的异常数据映射成友好的API响应,却怎么都搞不定。
比如我的Lambda会抛出这样的异常:
User some-user-id exists: java.lang.IllegalStateException java.lang.IllegalStateException: User some-user-id exists at u.c.c.e.s.lambda.user.handler.RegisterNewUserRequestHandler.handleRequest(RegisterNewUserRequestHandler.java:68) Caused by: com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException: The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: UONMOKNKVSEIL8EI6T6NVPODOJVV4KQNSO5AEMVJF66Q9ASUAAJG) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1630) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1302) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1056) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:3082) at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:3058) at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.executeUpdateItem(AmazonDynamoDBClient.java:2778) at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:2753) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.doUpdateItem(DynamoDBMapper.java:854) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$2.executeLowLevelRequest(DynamoDBMapper.java:594) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.execute(DynamoDBMapper.java:733) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:623) at com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.save(AbstractDynamoDBMapper.java:128) at uk.co.claritysoftware.exam.slammr.lambda.user.handler.RegisterNewUserRequestHandler.saveNewUserIfNotExists(RegisterNewUserRequestHandler.java:97) at uk.co.claritysoftware.exam.slammr.lambda.user.handler.RegisterNewUserRequestHandler.handleRequest(RegisterNewUserRequestHandler.java:63)
我本来写了正则匹配错误消息,想通过捕获组提取里面的用户ID,然后在API Gateway的映射模板里引用,但*$1被当成字符串字面量直接返回了*,根本起不到提取替换的作用。
目前只能用个临时方案,用下面的映射模板返回原生的Lambda错误消息:
#set($inputRoot = $input.path('$')) { "message" : "$inputRoot.errorMessage" }
但这个方案有两个大问题:一是完全依赖Lambda异常消息的具体格式,哪天异常消息变了,响应就会出问题;二是把原生的异常堆栈暴露给前端,这明显是不良实践,所以想请教下正确的实现方法。
补充说明
- 悬浮(i)图标显示内容如截图所示
- 我试过用\1或$1转义,结果响应里还是显示字面量的\1或$1,完全没效果
内容的提问来源于stack exchange,提问作者Nathan Russell
相关产品推荐
相关产品推荐

