прерывистая SMTP сломанная труба (errno 32) - PullRequest
1 голос
/ 05 ноября 2010

У меня есть скрипт на python, который отправляет несколько наборов писем (на разные адреса с разным содержимым), периодически используя smtplib в течение дня.Довольно часто (например, примерно 1 из 5 раз при отправке пакетов из более чем одного письма одновременно) я получаю IOError (errno: сломанный канал).Я пытаюсь сбросить и выйти из SMTP-сервера, а затем снова подключиться к серверу и попытаться выполнить повторную отправку, но всегда происходит сбой, если в первый раз произошел сбой (за тем же исключением).SMTP-сервер обслуживается колледжем и должен быть надежным (и разрешать электронную почту без входа в систему, пока вы находитесь в интрасети).

Игнорирование уродливости приведенного ниже кода (отсутствие DRY) может кто-нибудь посоветоватьболее надежный способ подключения?

Я создаю класс с именем EmailSet, который будет отправлять пакет из нескольких электронных писем с функцией-членом send_emails:

class EmailSet(object):
    ...
    def send_emails(self):
        try: # Connect to server
            server = smtplib.SMTP( smtp_server_name_str, 25)
            server.set_debuglevel(self.verbose)
            server.ehlo()
            for email in self.email_set:
                try: # send 1st mail
                    logging.debug("Sending email to %r" % email.recipients)        
                    response_dict = server.sendmail(email.fromaddr, email.recipients, email.msg_str())
                    logging.info("Sent email to %r" % email.recipients)        
                except Exception as inst:
                    logging.error('RD: %r' % response_dict)
                    logging.error("Email Sending Failed")
                    logging.error("%r %s" % ( type(inst), inst ) )
                    try: # send second mail
                        logging.info("Second Attempt to send to %r" % email.recipients)
                        try:
                            server.rset() 
                            server.quit()
                        except:
                            pass
                        time.sleep(60) # wait 60s
                        server = smtplib.SMTP( smtp_server_name_str, 25)
                        server.set_debuglevel(self.verbose)
                        server.ehlo()
                        response_dict = server.sendmail(email.fromaddr, email.recipients, email.msg_str())
                        logging.info("Sent email to %r (2nd Attempt)" % email.recipients)        
                    except Exception as inst:
                        try:
                            logging.error('RD: %r' % response_dict)
                        except:
                            pass
                        logging.error("Second Attempt Email Sending Failed")
        except:
            logging.debug("Can't connect to server")
        finally:
            logging.debug("Reseting and Quitting Server")
            server.rset()
            server.quit()
            logging.debug("Successfully Quit Server")
        return True

Любые мысли о том, как продолжить отладкуэтот?Сервер stmp не поддерживается мной, но должен быть в хорошем состоянии (используется для организации ~ 10 тыс. Человек).Первоначально я подключался и отключался от smtpserver после отправки каждого электронного письма, но это вызвало больше ошибок, чем этот метод.

Также было бы безопаснее использовать / usr / sbin / sendmail, а не smtplib?

1 Ответ

1 голос
/ 05 ноября 2010

Also would it be safer to use /usr/sbin/sendmail rather than smtplib?

С точки зрения обработки очереди сообщений и обработчика очередей для повторных попыток.Да, sendmail или другой локальный MTA могут обработать это для вас.

Any thoughts on how to proceed debugging this?

Перехват пакетов.Используйте wireshark, чтобы захватить трафик SMTP, посмотреть, что происходит.У вас есть широкая обработка исключений, которая не обязательно показывает вам точную ошибку.

...