Python函数内SMTP邮件发送异常:仅打印成功但未实际发送
邮件发送函数排查与修复
原问题代码
def send_mail(): recv = os.environ.get('mail_username') sender = 'alerts@.com' receivers = [recv] message = f"""From: QA-Security Gate Alerts <alerts@.com> To: To Person {recv} Subject: Azure function down Check Logs """ try: smt_obj = smtplib.SMTP('mailrelay.site.com') smt_obj.sendmail(sender, receivers, message) print("Successfully sent email") except Exception as e: logging.error('Sending mail Failed') raise e
调用方式:send_mail()
问题描述
上述代码直接在函数外运行时能正常发送邮件,但封装成send_mail函数后,虽然控制台打印了"Successfully sent email",但实际并未收到邮件。尝试返回SMTP对象并调用quit()的方式也无效:
# 修改后的函数内部 return smt_obj # 外部调用 mail = send_mail() mail.quit()
排查方向与修复方案
1. 邮件格式错误(最可能原因)
函数内的邮件内容字符串存在缩进问题:From/To/Subject这些邮件头字段前面带有空格,SMTP服务器会将这些带缩进的行识别为邮件正文的一部分,而非合法的邮件头,导致邮件被服务器拒绝或丢弃。
修复方法:移除邮件头部分的缩进,确保头字段顶格写:
message = f"""From: QA-Security Gate Alerts <alerts@.com> To: To Person {recv} Subject: Azure function down Check Logs """
2. SMTP连接未正确管理
Python的SMTP对象在被垃圾回收时会自动关闭连接,但函数执行完毕后,SMTP对象可能在邮件真正发送完成前就被销毁。即使返回对象调用quit(),也可能因为连接已提前失效而无效。
推荐使用with语句自动管理SMTP连接生命周期,确保邮件发送完成后再关闭连接:
def send_mail(): recv = os.environ.get('mail_username') sender = 'alerts@.com' receivers = [recv] # 修复邮件格式,移除头字段缩进 message = f"""From: QA-Security Gate Alerts <alerts@.com> To: To Person {recv} Subject: Azure function down Check Logs """ try: # 使用with语句管理SMTP连接 with smtplib.SMTP('mailrelay.site.com') as smt_obj: # 可选:有些服务器需要先发送EHLO命令标识客户端 smt_obj.ehlo() smt_obj.sendmail(sender, receivers, message) print("Successfully sent email") except Exception as e: logging.error('Sending mail Failed') raise e
3. 环境变量未正确获取
确认os.environ.get('mail_username')在函数内是否成功获取到有效值。如果该值为None,receivers会变成[None],部分SMTP服务器不会抛出异常,但会静默丢弃邮件。可以添加打印语句验证:
recv = os.environ.get('mail_username') print(f"Received email address: {recv}") # 验证是否获取到正确邮箱
4. SMTP服务器额外要求
部分SMTP服务器需要启用TLS加密,或者要求认证。可以尝试添加TLS相关代码(如果服务器支持):
with smtplib.SMTP('mailrelay.site.com') as smt_obj: smt_obj.ehlo() smt_obj.starttls() # 启用TLS加密 # 如果需要认证,添加以下两行(替换为实际账号密码) # smt_obj.login('your_username', 'your_password') smt_obj.sendmail(sender, receivers, message)
内容的提问来源于stack exchange,提问作者Abhishek Rai
相关产品推荐
相关产品推荐

