【发布时间】:2021-10-09 17:10:51
【问题描述】:
我使用以下内容创建电子邮件。
def createGmailEmailNoAttachments(self, messageBody, subject, toEmail, fromEmail, html=False):
try:
newMessage = MIMEMultipart()
newMessage['to']=toEmail
newMessage['from'] = fromEmail
newMessage['subject'] = subject
if html:
msg= MIMEText(messageBody, 'html')
else:
msg= MIMEText(messageBody)
newMessage.attach(msg)
raw = base64.urlsafe_b64encode(newMessage.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
except:
self.GLogger.error("An error was encountered while attempting to create gmail email")
tb = traceback.format_exc()
self.GLogger.exception(tb)
return False
我发送一封包含以下内容的电子邮件。
def gmailAPISendEmail(self, message, userID="me"):
try:
service = self.gmailAPIService
self.GLogger.info("Attempting to send email message")
request = service.users().messages().send(userId=userID, body=message)
response = self.executeGmailAPI_withretry(request)
if response is False:
return False
responseID = str(response['id'])
self.GLogger.info("Successfully sent email message with ID (" + responseID +")")
return responseID
except:
self.GLogger.error("Failed to send email message")
tb = traceback.format_exc()
self.GLogger.exception(tb)
return False
我在函数executeGmailAPI_withretry(request)中执行请求的地方
def executeGmailAPI_withretry(self, request, withHTTPObject = False):
try:
response_valid = False
num_retries = 0
while num_retries < 30:
try:
if withHTTPObject is True:
response = request.execute(http=self.http_toUse)
else:
response = request.execute()
response_valid = True
break
except socket.timeout:
num_retries = num_retries + 1
time.sleep(0.5*num_retries)
except:
self.GLogger.error("An error was encounrtered in executeGmailAPI_withretry")
try:
self.GLogger.error(f"The Method ID : {request.methodId}")
except:
pass
try:
self.GLogger.error(f"The uri : {request.uri}")
except:
pass
tb = traceback.format_exc()
self.GLogger.exception(tb)
num_retries = num_retries + 1
time.sleep(0.5*num_retries)
if response_valid is False:
self.GLogger.error(f"Could not resolve issue in 15 requests [{request}]")
return False
else:
return response
except:
self.GLogger.error("An error was encounrtered in executeGmailAPI_withretry")
tb = traceback.format_exc()
self.GLogger.exception(tb)
return False
我遇到的问题如下。有时,当我想用这三个函数发送电子邮件时,在执行service.users().messages().send(userId=userID, body=message) 的过程中会出现socket.timeout 错误。我的重试功能将尝试发送最多 30 次,中间会有一些时间延迟。但是,有时,当发生 socket.timeout 错误时,电子邮件仍然发送。这可能会导致发送多封相同的电子邮件。从代码的角度来看,只发送了一封电子邮件,因为service.users().messages().send(userId=userID, body=message) 只成功运行了一次而没有抛出错误。
因此,例如,我收到了 4 封相同的电子邮件,这意味着至少 3 次发送尝试出现了 socket.timeout 错误,其中 Gmail 确实发送了电子邮件,并且执行了第 4 次(或更多)尝试而没有抛出套接字.timeout 错误。
为什么Gmail API在发送邮件的时候会抛出socket.timeout错误,但还是继续发送邮件?
这在当前情况下造成了两难境地。
-
如果我处理了错误,那么它可以确保在第一次尝试时确实无法发送的电子邮件将被发送。但是,由于错误错误,它可能会导致发送多封相同的电子邮件。
-
如果我不处理错误,那么可以肯定的是,最多只会发送一封电子邮件。但是,如果邮件真的发不出去,那肯定是发不出去的。
理想的解决方案是,Gmail API 应该只在电子邮件确实无法发送时抛出错误。
【问题讨论】:
标签: python python-3.x gmail gmail-api gmail-imap