含无法解析字符的收件人名称触发NoMethodError问题求助
含特殊符号的收件人名称导致mail gem解析错误
从第三方数据源获取的用户姓名中,部分带有(R&D)或[TECH]这类部门后缀,使用ActionMailer发送邮件时,会触发mail gem抛出的NoMethodError错误。
问题复现
无需ActionMailer即可复现该问题:
# 正常解析场景 to = "Kris Leech <kris@example.com>" mail = Mail.new { to(to) } mail[:to].addrs # => [#<Mail::Address>] # 解析失败场景 to = "Kris Leech [TECH] <kris@example.com>" mail = Mail.new { to(to) } mail[:to].addrs # => NoMethodError: undefined method `addrs' for Mail::UnstructuredField
错误原因
方括号这类特殊符号会干扰mail gem的收件人字段解析逻辑,导致返回Mail::UnstructuredField对象(该对象不响应addrs方法),而非预期的Mail::StructuredField对象。查看具体解析错误:
mail[:to].errors # => [["To", "Kris Leech [TECH] <kris.leech@example.com>", #<Mail::Field::IncompleteParseError: Mail::AddressList can not parse |Kris Leech [TECH] <kris@example.com>|: Only able to parse up to "Kris Leech ">]]
解决方法
1. 用引号包裹收件人名称
将包含特殊符号的名称部分用双引号或单引号包裹,明确划分名称与邮箱地址的边界:
# 双引号示例 to = "\"Kris Leech [TECH]\" <kris@example.com>" # 单引号示例 to = "'Kris Leech [TECH]' <kris@example.com>" mail = Mail.new { to(to) } mail[:to].addrs # 正常返回Mail::Address对象数组
2. 手动构建Mail::Address对象
直接创建Mail::Address对象,绕过字符串解析环节,这是最可靠的方式:
address = Mail::Address.new address.display_name = "Kris Leech [TECH]" address.address = "kris@example.com" mail = Mail.new { to(address) } mail[:to].addrs # 可正常调用
3. 转义特殊字符
对名称中的特殊字符(如方括号、括号)进行转义,但这种方式兼容性不如前两种:
to = "Kris Leech \\[TECH\\] <kris@example.com>" mail = Mail.new { to(to) } mail[:to].addrs # 可正常解析
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

