SendGrid - NoMethodError (nil:NilClass의 `[]` 메서드 정의되지 않음)

안녕하세요,

SendGrid 웹훅을 검증 키와 함께 사용하기 시작했습니다. 그런데 대량의 초대장을 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 사용자가 아닌 목록에서 반송된 이메일에 대해 생성된 건가요?

이것이 바운스(반송)인지 확실하지 않습니다. 어떻게 확인해 볼 수 있을까요? 아마도 비디스코러스(non-discourse) 사용자에게 대량으로 초대장을 보냈을 때쯤일 가능성이 가장 높습니다.

Sendgrid에서 수신되는 이벤트 페이로드에 문제가 있는 것 같습니다. bounce 이벤트에서 status가 예상대로 설정되지 않는 것으로 보입니다.

<YOUR_SITE>/logs의 logster에서 백트레이스를 가져왔다면, env 탭에 요청 세부 정보가 있을 것입니다. 해당 페이로드의 정제된(sanitized) 사본을 공유해 주시겠습니까?

여기에는 정보가 많지 않습니다. 대부분을 여기에 올렸습니다.

요청하신 대로 전체 참조 정보는 아래에 첨부했습니다.

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 Su 5:54 pm

죄송합니다. 더 구체적으로 말씀드렸어야 했는데 그러지 못했습니다. 필요한 단서는 요청 본문(request body)에 있습니다. time 행 이후에 이 내용을 찾을 수 있어야 합니다. 확인하려면 위로 스크롤하거나 패널을 확장해야 할 수 있습니다.

안녕하세요,

Time 행 이후에는 추가 정보가 없습니다. 34개의 오류를 모두 확인해 보았지만, 포함되지 않은 것 같아 이상합니다.

네, 좀 이상하긴 합니다. 대신 SendGrid 대시보드에서 페이로드를 가져와 주실 수 있을까요?

최신 SendGrid 웹훅 문서에 따르면, 현재 Discourse의 엔드포인트는 문제없이 작동해야 하지만, 오류는 요청 페이로드와 관련된 문제를 가리키고 있어 샘플이 매우 유용할 것입니다.

이 문제를 해결해 보셨나요? 저에게도 동일한 코드 줄에서 같은 오류가 발생합니다:

저는 Ruby에 익숙하지 않지만, 오류 코드를 파싱하려고 시도할 때까지 JSON을 정상적으로 파싱하는 것 같습니다. Email::SMTP_STATUS_TRANSIENT_FAILURE는 다음을 가리킵니다:

Webhook.site에서 웹훅을 테스트할 때 Sendgrid가 실제로 전송하는 내용을 확인해 보았는데, 바운스(bounce)의 경우 다음과 같은 형태입니다:

[
  {
    "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"
  }
]

정상적으로 작동할 것 같은데 말이죠!

아하.. 여기서 제 질문에 스스로 답을 하고 있네요. 웹훅의 “테스트 통합” 버튼이 거짓말을 합니다..

실제로 존재하지 않는 이메일 주소로 이메일을 보냈을 때의 실제 페이로드는 다음과 같습니다:

[
  {
    "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개의 좋아요