英文:
emersion/go-imap - imap.FetchRFC822: invalid memory address or nil pointer dereference
问题
我正在尝试使用以下源代码从服务器获取所有电子邮件(此函数在主模块中调用):
package internal
import (
"fmt"
"io"
"io/ioutil"
"log"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
"github.com/emersion/go-message"
)
func FetchEMail(server string, username string, password string) error {
// 连接服务器
log.Println("连接到服务器...")
c, err := client.DialTLS(server, nil)
log.Println("已连接到 " + server)
defer c.Logout()
// 检查连接是否成功
if err != nil {
log.Println("连接错误")
return err
}
// 登录
log.Println("登录中...")
err = c.Login(username, password)
log.Println("已登录为 " + username)
// 检查登录是否成功
if err != nil {
log.Println("登录错误")
return err
}
// 选择收件箱
log.Println("选择收件箱...")
mbox, err := c.Select("INBOX", false)
log.Println("已选择收件箱")
// 检查选择是否成功
if err != nil {
return err
}
// 获取所有邮件
log.Println("获取所有邮件...")
seqset := new(imap.SeqSet)
seqset.AddRange(1, mbox.Messages)
items := []imap.FetchItem{imap.FetchRFC822}
messages := make(chan *imap.Message, 10)
done := make(chan error, 1)
go func() {
done <- c.Fetch(seqset, items, messages)
}()
// 检查获取是否成功
if err := <-done; err != nil {
log.Println("获取错误")
return err
}
log.Println("运行成功 - 终止...")
return nil
}
这导致以下错误:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5ee505]goroutine 1 [running]:
我已经尝试过imap.FetchEvelope()
,它可以工作,但由于某种原因imap.FetchRFC822
不起作用。
我的主要目标是从所有电子邮件中导出所有附件(.gz、.zip等),这就是为什么我需要整个电子邮件而不仅仅是信封的原因。
英文:
I am trying to fetch all E-Mails from the Server with the following source Code (this function is called in the main module):
package internal
import (
"fmt"
"io"
"io/ioutil"
"log"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
"github.com/emersion/go-message"
)
func FetchEMail(server string, username string, password string) error {
//Connect to Server
log.Println("Connecting to server...")
c, err := client.DialTLS(server, nil)
log.Println("Connected to " + server)
defer c.Logout()
//check if connection successful
if err != nil {
log.Println("In connection Error")
return err
}
//err = nil
//Login
log.Println("Logging in...")
err = c.Login(username, password)
log.Println("Logged in as " + username)
//check if login successful
if err != nil {
log.Println("In login Error")
return err
}
//Select INBOX
log.Println("Selecting INBOX...")
mbox, err := c.Select("INBOX", false)
log.Println("Selected INBOX")
//check if select successful
if err != nil {
return err
}
//Fetch all messages
log.Println("Fetching all messages...")
seqset := new(imap.SeqSet)
seqset.AddRange(1, mbox.Messages)
items := []imap.FetchItem{imap.FetchRFC822}
messages := make(chan *imap.Message, 10)
done := make(chan error, 1)
go func() {
done <- c.Fetch(seqset, items, messages)
}()
//check if fetch successful
if err := <-done; err != nil {
log.Println("In fetch Error")
return err
}
log.Println("Run Successful - Terminating...")
return nil
}
This results into the following error:
> panic: runtime error: invalid memory address or nil pointer dereference
> [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5ee505]
>
> goroutine 1 [running]:
I already have tried imap.FetchEvelope() which works, but for some reason imap.FetchRFC822 does not work.
My main goal is to export all E-Mail attachments (.gz, .zip, ...) from all E-Mails, that is why I need the whole E-Mail, not only the Envelope.
答案1
得分: 1
我认为问题出在这一行代码items := []imap.FetchItem{imap.FetchRFC822}
。首先,让我们澄清一下FetchItem
类型是什么。它表示可以获取的电子邮件的不同部分(信封、正文、UID、标志等)。然后,让我们谈谈Fetch
方法。它期望传入一个imap.FetchItem
切片。它从电子邮件中检索由切片指定的所有部分。所以修复你的问题的方法是将这一行替换为items := []imap.FetchItem{imap.FetchRFC822, imap.FetchEnvelope}
。我已经修复并测试了你的程序,你可以从下面的代码片段中看到:
package main
import (
"fmt"
"log"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
)
func FetchEMail(server string, username string, password string) error {
// Connect to Server
log.Println("Connecting to server...")
c, err := client.Dial(server)
log.Println("Connected to " + server)
defer c.Logout()
// check if connection successful
if err != nil {
log.Println("In connection Error")
return err
}
// Login
log.Println("Logging in...")
err = c.Login(username, password)
log.Println("Logged in as " + username)
// check if login successful
if err != nil {
log.Println("In login Error")
return err
}
// Select INBOX
log.Println("Selecting INBOX...")
mbox, err := c.Select("INBOX", false)
log.Println("Selected INBOX")
// check if select successful
if err != nil {
return err
}
// Fetch all messages
log.Println("Fetching all messages...")
seqset := new(imap.SeqSet)
seqset.AddRange(1, mbox.Messages)
items := []imap.FetchItem{imap.FetchRFC822, imap.FetchEnvelope}
messages := make(chan *imap.Message, 10)
done := make(chan error, 1)
go func() {
done <- c.Fetch(seqset, items, messages)
}()
for msg := range messages {
fmt.Printf("suject: %v\n", msg.Envelope.Subject)
}
// check if fetch successful
if err := <-done; err != nil {
log.Println("In fetch Error")
return err
}
log.Println("Run Successful - Terminating...")
return nil
}
func main() {
err := FetchEMail("xxxxxxx", "xxxxx", "xxxxx")
if err != nil {
panic(err)
}
}
在最后,我添加了一个for
循环来打印检索到的电子邮件的主题。在这里,你可以用自己的逻辑替换这段代码。nil pointer dereference
错误消失了。如果这解决了你的问题,请告诉我!
英文:
I think the issue was in this line items := []imap.FetchItem{imap.FetchRFC822}
.
First, let's clarify what the FetchItem
type is. This represents the different parts of an email that can be fetched (envelope, body, UID, flags, and so on).
Then, let's talk about the Fetch
method. It expects a slice of imap.FetchItem
passed in. It retrieves from the emails all of the parts specified by the slice.
So what fixes your issue is replacing this line with items := []imap.FetchItem{imap.FetchRFC822, imap.FetchEnvelope}
.
I fixed and tested your program as you can see from the code snippet below:
package main
import (
"fmt"
"log"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
)
func FetchEMail(server string, username string, password string) error {
// Connect to Server
log.Println("Connecting to server...")
c, err := client.Dial(server)
log.Println("Connected to " + server)
defer c.Logout()
// check if connection successful
if err != nil {
log.Println("In connection Error")
return err
}
// Login
log.Println("Logging in...")
err = c.Login(username, password)
log.Println("Logged in as " + username)
// check if login successful
if err != nil {
log.Println("In login Error")
return err
}
// Select INBOX
log.Println("Selecting INBOX...")
mbox, err := c.Select("INBOX", false)
log.Println("Selected INBOX")
// check if select successful
if err != nil {
return err
}
// Fetch all messages
log.Println("Fetching all messages...")
seqset := new(imap.SeqSet)
seqset.AddRange(1, mbox.Messages)
items := []imap.FetchItem{imap.FetchRFC822, imap.FetchEnvelope}
messages := make(chan *imap.Message, 10)
done := make(chan error, 1)
go func() {
done <- c.Fetch(seqset, items, messages)
}()
for msg := range messages {
fmt.Printf("suject: %v\n", msg.Envelope.Subject)
}
// check if fetch successful
if err := <-done; err != nil {
log.Println("In fetch Error")
return err
}
log.Println("Run Successful - Terminating...")
return nil
}
func main() {
err := FetchEMail("xxxxxxx", "xxxxx", "xxxxx")
if err != nil {
panic(err)
}
}
Near the end, I added a for
to print the subject of the retrieved emails. Here, you can replace the code with your own logic. The nil pointer dereference
error disappears.
Let me know if this solves your issue!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论