AWS AppSync不显示Lambda Resolver exampappateTemplate中的自定义错误属性

发布于 2025-01-25 05:18:37 字数 2680 浏览 1 评论 0原文

我们正在尝试使用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模板,我们只是将nameMessage> 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文