SendGrid - NoMethodError(未定义的方法 `[]',用于 nil:NilClass)

你好,

已开始使用带有验证密钥的 SendGrid Webhook。现在收到大量此类错误。曾使用 SendGrid 发送过批量邀请。

app/controllers/webhooks_controller.rb:29:in `block in sendgrid'
app/controllers/webhooks_controller.rb:24:in `each'
app/controllers/webhooks_controller.rb:24:in `sendgrid'
actionpack (7.0.7) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (7.0.7) lib/abstract_controller/base.rb:215:in `process_action'
actionpack (7.0.7) lib/action_controller/metal/rendering.rb:165:in `process_action'
actionpack (7.0.7) lib/abstract_controller/callbacks.rb:234:in `block in process_action'
activesupport (7.0.7) lib/active_support/callbacks.rb:107:in `run_callbacks'
actionpack (7.0.7) lib/abstract_controller/callbacks.rb:233:in `process_action'
actionpack (7.0.7) lib/action_controller/metal/rescue.rb:23:in `process_action'
actionpack (7.0.7) lib/action_controller/metal/instrumentation.rb:67:in `block in process_action'
activesupport (7.0.7) lib/active_support/notifications.rb:206:in `block in instrument'
activesupport (7.0.7) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (7.0.7) lib/active_support/notifications.rb:206:in `instrument'
actionpack (7.0.7) lib/action_controller/metal/instrumentation.rb:66:in `process_action'
actionpack (7.0.7) lib/action_controller/metal/params_wrapper.rb:259:in `process_action'
activerecord (7.0.7) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (7.0.7) lib/abstract_controller/base.rb:151:in `process'
actionview (7.0.7) lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler (3.1.1) lib/mini_profiler/profiling_methods.rb:85:in `block in profile_method'
actionpack (7.0.7) lib/action_controller/metal.rb:188:in `dispatch'
actionpack (7.0.7) lib/action_controller/metal.rb:251:in `dispatch'
actionpack (7.0.7) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (7.0.7) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (7.0.7) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (7.0.7) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (7.0.7) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (7.0.7) lib/action_dispatch/routing/route_set.rb:852:in `call'
lib/middleware/omniauth_bypass_middleware.rb:64:in `call'
rack (2.2.8) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.8) lib/rack/conditional_get.rb:40:in `call'
rack (2.2.8) lib/rack/head.rb:12:in `call'
actionpack (7.0.7) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:389:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
rack (2.2.8) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.8) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/cookies.rb:704:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.7) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.7) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/show_exceptions.rb:29:in `call'
logster (2.13.1) lib/logster/middleware/reporter.rb:40:in `call'
railties (7.0.7) lib/rails/rack/logger.rb:40:in `call_app'
railties (7.0.7) lib/rails/rack/logger.rb:27:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/request_id.rb:26:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
rack (2.2.8) lib/rack/method_override.rb:24:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/executor.rb:14:in `call'
rack (2.2.8) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/host_authorization.rb:131:in `call'
rack-mini-profiler (3.1.1) lib/mini_profiler.rb:260:in `call'
message_bus (4.3.8) lib/message_bus/rack/middleware.rb:60:in `call'
lib/middleware/request_tracker.rb:233:in `call'
railties (7.0.7) lib/rails/engine.rb:530:in `call'
railties (7.0.7) lib/rails/railtie.rb:226:in `public_send'
railties (7.0.7) lib/rails/railtie.rb:226:in `method_missing'
rack (2.2.8) lib/rack/urlmap.rb:74:in `block in call'
rack (2.2.8) lib/rack/urlmap.rb:58:in `each'
rack (2.2.8) lib/rack/urlmap.rb:58:in `call'
unicorn (6.1.0) lib/unicorn/http_server.rb:634:in `process_client'
unicorn (6.1.0) lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn (6.1.0) lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn (6.1.0) lib/unicorn/http_server.rb:143:in `start'
unicorn (6.1.0) bin/unicorn:128:in `<top (required)>'
vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `load'
vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `<main>'

ENV

|REQUEST_URI|/webhooks/sendgrid|
|REQUEST_METHOD|POST|
|HTTP_USER_AGENT|SendGrid Event API|

这似乎与这里几周前修复的一个问题相同:Sendgrid error: NoMethodError (undefined method `[]' for nil:NilClass) - #3 by Terrapop

这些是为您的列表中非 discourse 用户的退订用户生成的吗?

不确定它们是否是反弹,我们该如何检查?这很可能发生在我们将非 Discourse 用户批量邀请的时候。

Sendgrid 接收到的事件负载可能存在问题。看起来 bounce 事件的 status 未按预期设置。

假设您在 \u003cYOUR_SITE\u003e/logs 的 logster 中获得了堆栈跟踪,那么 env 选项卡应该包含请求的详细信息。您能否从那里提供一个已清理的负载副本?

这里的信息不多,大部分是我在这里提供的。

根据要求,完整参考信息已放在下面

hostname serverhostname
process_id 248749
application_version a8d6dc4d3a5c3d937ff0bb162c93ec628428cda1
HTTP_HOST forum.URL.co.uk
REQUEST_URI /webhooks/sendgrid
REQUEST_METHOD POST
HTTP_USER_AGENT SendGrid Event API
HTTP_X_FORWARDED_FOR IPADDRESS
HTTP_X_REAL_IP IPADDRESS
time 周日 下午5:54

抱歉,我应该说得更具体一些。请求正文包含了所需的线索。您应该能在 time 行之后找到它。您可能需要向上滚动或展开面板才能看到它。

您好,

时间行之后没有进一步的信息了,我已经检查了所有 34 个错误。这似乎很奇怪,但为什么不包含在内呢?

是的,这很奇怪。您能否从 SendGrid 仪表板中检索载荷?

根据最新的 SendGrid Webhook 文档,Discourse 中的当前端点应该可以正常工作,但错误指向请求载荷存在问题,因此提供示例将非常有帮助。

您弄清楚这个问题了吗?我遇到了同样的错误,在同一行代码上:

我不熟悉 Ruby,但它似乎可以很好地解析 JSON,直到尝试解析错误代码 Email::SMTP_STATUS_TRANSIENT_FAILURE 指向:

我在 Webhook.site 上检查了 Sendgrid 在我测试 Webhook 时实际发送的内容,对于弹跳,它看起来像这样:

[
  {
    "email": "example@test.com",
    "timestamp": 1740136261,
    "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>",
    "event": "bounce",
    "category": [
      "cat facts"
    ],
    "sg_event_id": "ovGQ2rRo8ytNezHPDq-7Ig==",
    "sg_message_id": "14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0",
    "reason": "500 unknown recipient",
    "status": "5.0.0"
  }
]

看起来应该可以工作!

嗯……我自己回答自己的问题,Webhook 的“测试集成”按钮会骗你……

如果我实际发送一封电子邮件到一个不存在的电子邮件地址,实际的载荷是这样的:

[
  {
    "bounce_classification": "Unclassified",
    "email": "noemail@this.does.not.exist.tld",
    "event": "bounce",
    "reason": "unable to get mx info: failed to get IPs from PTR record: lookup <nil>: unrecognized address",
    "sg_event_id": "Ym91bmNlLTQtNTA0ODUxOTUtZXVvMmlLeGRTYXlQRjRZRTQtLUk3QS0w",
    "sg_message_id": "euo2iKxdSayPF4YE4--I7A.recvd-5f54b5d587-pczjm-1-67BADEEA-6.0",
    "smtp-id": "<870b3a2a-160c-4fc8-bc9a-bd0d5b943b81@forum.umbraco.com>",
    "timestamp": 1740300320,
    "tls": 0,
    "type": "blocked"
  }
]

在这里我们看到了:没有 status 字段。

这是当我故意使用一个不存在的域时,我觉得这应该被处理,也许 \"type\": \"blocked\" 可以作为 Discourse 查找的指示符。

作为另一个尝试,我在 outlook.com 前面加了一些无意义的内容,这确实给了我一个有效的载荷:

[
  {
    "bounce_classification": "Invalid Address",
    "email": "oeihoiwehitwiohtriuweruiwerwierhwuerguiwerg@outlook.com",
    "event": "bounce",
    "ip": "149.72.1.78",
    "reason": "550 5.5.0 Requested action not taken: mailbox unavailable (S2017062302). [HK3PEPF0000021E.apcprd03.prod.outlook.com 2025-02-23T08:54:35.950Z 08DD502499E1A0AA]",
    "sg_event_id": "Ym91bmNlLTAtNTA0ODUxOTUtQWJFZ2pVejZUUFd3MnJNTnJabDg4Zy0w",
    "sg_message_id": "AbEgjUz6TPWw2rMNrZl88g.recvd-786d47b7ff-tsp86-1-67BAE249-D.0",
    "smtp-id": "<d8dc253e-6e9a-4418-8478-60780eb4898c@forum.umbraco.com>",
    "status": "5.5.0",
    "timestamp": 1740300876,
    "tls": 1,
    "type": "bounce"
  }
]

已提交 PR!

@cultiv 感谢您深入研究问题并花时间提交 PR。我已将您的 PR 作为基础,并将修复程序合并到 FIX: No method error in `WebhooksController#sendgrid` (#31495) · discourse/discourse@209d289 · GitHub 中。

2 个赞

太棒了,这非常有帮助。没有你我真不知道该怎么办 :sweat_smile:

谢谢,我已经更新了,手动测试现在可以正确执行,错误日志干净,我可以在邮件日志中看到邮件被退回了 :raising_hands:

1 个赞