You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过SNS转发S3事件至Lambda时,解析S3Event遇空引用异常

问题

需要让多个Lambda订阅S3存储桶事件,但S3不支持直接多订阅,因此引入SNS作为中转,架构流程为:S3Event → SNS → 多个Lambda消费者。目前Lambda已能通过SNSEvent结合ILambdaContext正常触发,但在解析SNSEvent消息中的S3Event时,出现**“对象引用未设置到对象实例”**的异常。已确认消息非空,且添加了过滤EventSource为aws:s3记录的逻辑,但问题仍存在,想了解解析S3Event是否有特殊要求。

相关代码:

foreach (var record in snsEvent.Records)
{
    var snsRecord = record.Sns;
    if (string.IsNullOrEmpty(snsRecord.Message))
    {
      logger.Error("Message is empty", record);
      throw new Exception("Message is empty");
    }

  // Object reference not set to an instance of an object.
  var s3Event = JsonSerializer.Deserialize<S3Event>(snsRecord.Message);
  logger.Info($"{s3Event.Records.FirstOrDefault()?.S3.Object.Key}", snsEvent);

  await ProcessParsedEvent(s3Event, context);
}
解决方案

解析SNS中转的S3Event确实存在几个容易忽略的特殊要求,针对你的问题可以从以下几点排查解决:

  • 处理SNS的消息嵌套包装:S3发送到SNS的事件消息会被SNS额外包装一层结构,并非直接是纯S3Event JSON。比如实际的S3Event内容可能处于Message字段的嵌套节点中,或者消息本身带有转义字符(如双引号被转义),直接反序列化会导致S3Event或其内部属性为null。
  • 使用AWS适配的序列化工具:AWS SDK中的S3Event类有特定的序列化规则,默认的JsonSerializer(如System.Text.Json)可能无法正确处理AWS的蛇形命名(如eventSource与EventSource的映射)或特殊字段。建议改用AWS SDK自带的Amazon.Lambda.Serialization.SystemTextJson或Amazon.Lambda.Serialization.Json来反序列化,它们已适配AWS事件格式。
  • 补充逐层空值检查:即使反序列化成功,s3Event.Records可能为空集合,调用FirstOrDefault()后直接访问.S3.Object.Key会触发空引用异常。需在访问嵌套属性前逐层做null校验:
    var firstRecord = s3Event?.Records?.FirstOrDefault();
    if (firstRecord != null && firstRecord.S3 != null && firstRecord.S3.Object != null)
    {
        logger.Info(firstRecord.S3.Object.Key, snsEvent);
    }
    
  • 开启SNS的原始消息投递:确认SNS订阅Lambda时是否开启了Raw Message Delivery选项。未开启时,SNS会给消息添加额外元数据包装,导致你拿到的Message字段不是纯S3Event JSON;开启后,SNS会直接传递S3的原始事件消息,减少嵌套层级。

内容的提问来源于stack exchange,提问作者Pogrindis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:06:04