AWS AppSync不显示Lambda Resolver exampappateTemplate中的自定义错误属性
我们正在尝试使用GraphQL使用自定义错误状态代码,以便我们的上游服务可以更好地利用所抛出的错误。
我们有一个简单的错误类,将基本错误
类扩展到包括状态代码:
export class ErrorWithStatusCode extends Error {
public statusCode: number;
constructor({
message,
name,
statusCode,
}: {
message: string;
name: string;
statusCode: number;
}) {
super(message);
this.name = name;
this.statusCode = statusCode;
}
}
export class BadRequestError extends ErrorWithStatusCode {
constructor(message: string) {
super({
message,
name: `BAD_REQUEST`,
statusCode: 400,
});
}
}
然后我们在代码中抛出了该错误:
if (existingResource) {
throw new BadRequestError('An account with the email address already exists');
}
在日志中,我们看到lambda Invoke错误:
2022-04-29T13:42:56.530Z 0e1688ac-89f1-46a7-b592-d6aeceb83fd7 ERROR Invoke Error
{
"errorType": "BAD_REQUEST",
"errorMessage": "An account with the email address already exists",
"name": "BAD_REQUEST",
"statusCode": 400,
"stack": [
"BAD_REQUEST: An account with the email address already exists",
" at Runtime.main [as handler] (/var/task/index.js:26908:19)",
" at processTicksAndRejections (internal/process/task_queues.js:95:5)"
]
}
然后在我们的VTL模板,我们只是将name
和Message> Message>的所有属性关联到Custom
errorInfo
对象如上所述在这里
$ util.error(字符串,字符串,对象,对象) 引发自定义错误。如果是 模板检测请求或调用的错误 结果。此外,一个错误类型字段,数据字段和一个 可以指定ErrorInfo字段。数据值将添加到 GraphQL响应中的相应错误块内部错误。笔记: 数据将根据查询选择集过滤。 errorInfo 值将添加到在相应的错误块中内部错误中的错误块 GraphQL响应。注意:ErrorInfo不会根据 查询选择集。
#if (!$util.isNull($ctx.error))
$utils.error($ctx.error.errorMessage, $ctx.error.name, $ctx.result, $ctx.error)
#end
$utils.toJson($ctx.result)
但是,当我们从AppSync(使用控制台)中恢复错误时,我们没有任何其他错误属性:
{
"data": null,
"errors": [
{
"path": [
"createResource"
],
"data": null,
"errorType": null,
"errorInfo": {
"message": "An account with the email address already exists",
"type": "Lambda:Unhandled"
},
"locations": [
{
"line": 2,
"column": 5,
"sourceName": null
}
],
"message": "A custom error was thrown from a mapping template."
}
]
}
We are trying to use custom error status codes with GraphQL so that our upstream services can better utilize the errors thrown.
We have a simple error class that extends the base Error
class to include a status code:
export class ErrorWithStatusCode extends Error {
public statusCode: number;
constructor({
message,
name,
statusCode,
}: {
message: string;
name: string;
statusCode: number;
}) {
super(message);
this.name = name;
this.statusCode = statusCode;
}
}
export class BadRequestError extends ErrorWithStatusCode {
constructor(message: string) {
super({
message,
name: `BAD_REQUEST`,
statusCode: 400,
});
}
}
And then we throw that error in our code like so:
if (existingResource) {
throw new BadRequestError('An account with the email address already exists');
}
Inside our logs we see the Lambda invoke error:
2022-04-29T13:42:56.530Z 0e1688ac-89f1-46a7-b592-d6aeceb83fd7 ERROR Invoke Error
{
"errorType": "BAD_REQUEST",
"errorMessage": "An account with the email address already exists",
"name": "BAD_REQUEST",
"statusCode": 400,
"stack": [
"BAD_REQUEST: An account with the email address already exists",
" at Runtime.main [as handler] (/var/task/index.js:26908:19)",
" at processTicksAndRejections (internal/process/task_queues.js:95:5)"
]
}
Then in our VTL template, we just associate all properties outside of name
and message
to the custom errorInfo
object as described here
$util.error(String, String, Object, Object)
Throws a custom error. This can be used in request or response mapping templates if the
template detects an error with the request or with the invocation
result. Additionally, an errorType field, a data field, and a
errorInfo field can be specified. The data value will be added to the
corresponding error block inside errors in the GraphQL response. Note:
data will be filtered based on the query selection set. The errorInfo
value will be added to the corresponding error block inside errors in
the GraphQL response. Note: errorInfo will NOT be filtered based on
the query selection set.
#if (!$util.isNull($ctx.error))
$utils.error($ctx.error.errorMessage, $ctx.error.name, $ctx.result, $ctx.error)
#end
$utils.toJson($ctx.result)
But when we get the error back from AppSync (using the console), we do not have any additional error properties:
{
"data": null,
"errors": [
{
"path": [
"createResource"
],
"data": null,
"errorType": null,
"errorInfo": {
"message": "An account with the email address already exists",
"type": "Lambda:Unhandled"
},
"locations": [
{
"line": 2,
"column": 5,
"sourceName": null
}
],
"message": "A custom error was thrown from a mapping template."
}
]
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论