2

我目前正在尝试为 Lambda API 设置 XRay。我无法获得不是 200 的堆栈跟踪或 statusCode。我遇到了一个简单地引发 500 错误的端点。这里的想法是,我的代码中的任何错误都会冒泡到带有错误处理程序的最终 catch 语句,该错误处理程序返回 500 并记录错误。我还希望查看 XRay 中相关错误的堆栈跟踪,并按 500 个响应排序以找到所述错误。

该函数看起来像这样(它在 Typescript 中):

忽略明显的错误,缺少导入等。我基本上只考虑了重要的部分。

import AWSXRay from 'aws-xray-sdk';
import Logger from "../../common/utils/logger";
import {
  AlbEvent,
  ALBReturnType,
  LambdaContext,
  ApiErrorResponse,
} from "src/common/types";

export const formatApiError = (error: ApiError): ApiErrorResponse => ({
 statusCode: error.statusCode,
 Errors: typeof error.body === "string" ? [error.body] : error.body,
})

export const handleError = (
 segment: AWSXRay.Segment,
 ctx: LambdaContext, 
 cb: (x:any, y?:any) => void,
 logger: Logger,
 error: Error | ApiError
): Promise<ApiErrorResponse | void | String> => {

 const subsegment = segment.addNewSubsegment('handleError');
 subsegment.addError(error);

 if (error instanceof ApiError) {

   const response = JSON.stringify(formatApiError(error as ApiError));
   segment.close()
   return Promise.reject(response);
  } else {

   logger.error("Internal Server Error: ", error);
   const response = JSON.stringify(formatApiError(new ApiError(500, "Internal Server Error: ")));

   segment.close()
   return Promise.reject(response);
  }
};


const handler = async (
 event: AlbEvent,
 context: LambdaContext,
 cb: () => void
): Promise<String> => {
  const segment = AWSXRay.getSegment(); 
  logger.child({
    requestId: context.requestId,
  }); // Pino logger
  return handleError(segment as AWSXRay.Segment, context, cb, logger, new Error("Error: oh no")) 

}

export { handler };

我对 API 的响应如下所示(Postman 确实将其识别为 500 错误):

{
    "statusCode": 500,
    "Errors": [
        "Error: oh no"
    ]
}

但是 XRay 控制台只有 200 个状态码: XRay only 200 response

并且没有可见的堆栈跟踪: 没有堆栈跟踪

跟踪似乎也没有捕获对 errorHandler 函数或处理程序的调用:

跟踪中没有函数

从我在这个线程中读到的内容:https ://github.com/aws/aws-xray-sdk-node/issues/148

您只需调用“getSegment”即可获取自动生成的 nodejs lambda 根段。

还值得注意的是,我正在使用 API Gateway Lambda 与 lambda 错误正则表达式/映射模板的集成。显然,这是 XRay 记录的响应的下游,但也许我返回的格式不是 XRay 默认期望的标准?

4

1 回答 1

1

从片段中,subsegmentinhandError永远不会关闭,因此永远不会被发送出去。请参阅https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-subsegments.html以关闭每个打开的子段。

于 2020-07-07T08:08:18.447 回答