emersion/go-imap – imap.FetchRFC822:无效的内存地址或空指针解引用

huangapple go评论78阅读模式
英文:

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 (
&quot;fmt&quot;
&quot;io&quot;
&quot;io/ioutil&quot;
&quot;log&quot;
&quot;github.com/emersion/go-imap&quot;
&quot;github.com/emersion/go-imap/client&quot;
&quot;github.com/emersion/go-message&quot;
)
func FetchEMail(server string, username string, password string) error {
//Connect to Server
log.Println(&quot;Connecting to server...&quot;)
c, err := client.DialTLS(server, nil)
log.Println(&quot;Connected to &quot; + server)
defer c.Logout()
//check if connection successful
if err != nil {
log.Println(&quot;In connection Error&quot;)
return err
}
//err = nil
//Login
log.Println(&quot;Logging in...&quot;)
err = c.Login(username, password)
log.Println(&quot;Logged in as &quot; + username)
//check if login successful
if err != nil {
log.Println(&quot;In login Error&quot;)
return err
}
//Select INBOX
log.Println(&quot;Selecting INBOX...&quot;)
mbox, err := c.Select(&quot;INBOX&quot;, false)
log.Println(&quot;Selected INBOX&quot;)
//check if select successful
if err != nil {
return err
}
//Fetch all messages
log.Println(&quot;Fetching all messages...&quot;)
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 &lt;- c.Fetch(seqset, items, messages)
}()
//check if fetch successful
if err := &lt;-done; err != nil {
log.Println(&quot;In fetch Error&quot;)
return err
}
log.Println(&quot;Run Successful - Terminating...&quot;)
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 (
	&quot;fmt&quot;
	&quot;log&quot;

	&quot;github.com/emersion/go-imap&quot;
	&quot;github.com/emersion/go-imap/client&quot;
)

func FetchEMail(server string, username string, password string) error {
	// Connect to Server
	log.Println(&quot;Connecting to server...&quot;)

	c, err := client.Dial(server)
	log.Println(&quot;Connected to &quot; + server)
	defer c.Logout()

	// check if connection successful
	if err != nil {
		log.Println(&quot;In connection Error&quot;)
		return err
	}

	// Login
	log.Println(&quot;Logging in...&quot;)
	err = c.Login(username, password)
	log.Println(&quot;Logged in as &quot; + username)

	// check if login successful
	if err != nil {
		log.Println(&quot;In login Error&quot;)
		return err
	}

	// Select INBOX
	log.Println(&quot;Selecting INBOX...&quot;)
	mbox, err := c.Select(&quot;INBOX&quot;, false)
	log.Println(&quot;Selected INBOX&quot;)

	// check if select successful
	if err != nil {
		return err
	}

	// Fetch all messages
	log.Println(&quot;Fetching all messages...&quot;)
	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 &lt;- c.Fetch(seqset, items, messages)
	}()

	for msg := range messages {
		fmt.Printf(&quot;suject: %v\n&quot;, msg.Envelope.Subject)
	}

	// check if fetch successful
	if err := &lt;-done; err != nil {
		log.Println(&quot;In fetch Error&quot;)
		return err
	}

	log.Println(&quot;Run Successful - Terminating...&quot;)
	return nil
}

func main() {
	err := FetchEMail(&quot;xxxxxxx&quot;, &quot;xxxxx&quot;, &quot;xxxxx&quot;)
	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!

huangapple
  • 本文由 发表于 2022年12月20日 18:33:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/74861701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定