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

Devise通过ActiveJob发送邮件失败,求调试与解决方案

Troubleshooting Devise Email Delivery with ActiveJob/Sidekiq

First off, great job getting the Devise tasks into your Sidekiq queue—you’ve already narrowed down the issue a lot. Let’s walk through Devise’s email logic and actionable debugging steps to figure out why those emails still aren’t hitting inboxes.

Understanding Devise’s Email Flow

When you override send_devise_notification in your User model, you’re replacing Devise’s default synchronous email sending with ActiveJob’s async delivery. This is the right approach, but Devise’s mailer (by default Devise::Mailer) has a few subtle configuration hooks that might be tripping you up:

  • Devise pulls its mailer settings from config/initializers/devise.rb, not just your global ActionMailer config.
  • Even if the Sidekiq job shows as "done", silent failures (like missing SMTP credentials for Devise’s mailer, or suppressed exceptions) can prevent actual delivery.

Debugging Steps to Try

1. Verify Devise’s Mailer Configuration

Check your config/initializers/devise.rb for any overrides that might conflict with your working ActionMailer setup:

# Make sure this points to the correct mailer (default is Devise::Mailer)
config.mailer = 'Devise::Mailer'

# Ensure Devise isn't overriding delivery_method or other critical settings
# If you have custom SMTP settings, confirm they match your global ActionMailer config

It’s easy to accidentally set a different delivery_method here that doesn’t align with your working mail setup.

2. Explicitly Specify the Queue in send_devise_notification

Even though you added the queue to sidekiq.yml, explicitly defining the queue in your notification method ensures Devise uses the correct one (no relying on default fallback logic):

def send_devise_notification(notification, *args)
  Rails.logger.info "Triggering Devise notification: #{notification} for user #{id}"
  devise_mailer.send(notification, self, *args).deliver_later(queue: 'XXX_default_mailer_queue')
end

The log line will also help you confirm the method is actually being called when you trigger a Devise action (like password reset).

3. Dig Into Sidekiq and ActionMailer Logs

A job showing "done: 0.415" doesn’t mean the email was sent—it just means the job ran without uncaught exceptions. Here’s how to get more detail:

  • Sidekiq Web UI: If you have it enabled, check the job’s payload to confirm the notification type, user ID, and arguments are correct. Look for any hidden error messages in the job’s details (sometimes exceptions are swallowed if they’re handled internally).
  • ActionMailer Verbose Logging: Update your environment config (e.g., config/environments/production.rb) to log every step of email delivery:
    config.action_mailer.logger = Logger.new(STDOUT)
    config.action_mailer.raise_delivery_errors = true
    
    This will show you if the mailer is connecting to your SMTP server, if the email is being generated correctly, or if there’s a delivery failure (like a rejected recipient or authentication error).

4. Test deliver_now Directly in the Console

Since you mentioned deliver_now renders the email but doesn’t send it, test this directly in your Rails console to see what’s happening:

user = User.first
mail = user.devise_mailer.password_reset_instructions(user)
mail.deliver_now
# Check the output for any errors
puts mail.inspect # Verify the email has the correct to/from/subject

This will surface any immediate errors that might be suppressed in the web request flow.

5. Check for Silent Failures in ActiveJob

Sometimes ActiveJob swallows exceptions if they’re not properly logged. Add an error handler to your send_devise_notification method to catch issues:

def send_devise_notification(notification, *args)
  begin
    devise_mailer.send(notification, self, *args).deliver_later(queue: 'XXX_default_mailer_queue')
  rescue => e
    Rails.logger.error "Failed to send Devise notification #{notification}: #{e.message}"
    raise e # Re-raise if you want Sidekiq to retry the job
  end
end

Key Takeaway

Since your other ActiveJob/ActionMailer emails work, the issue is almost certainly tied to Devise’s specific mailer configuration or a hidden error in the Devise email flow. The logs and direct console testing will be your best tools to pinpoint exactly where the delivery is breaking down.

内容的提问来源于stack exchange,提问作者A. Neumann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:08:54