6

How can I get Flask to send me an email if any 404 or 500 errors occur in the application? I inserted the following in my config.py which I came across here, but I don't receive any emails. I'm new to Flask so please excuse any mistakes.

from app import app

ADMINS = ['myemail@domain.com']
if not app.debug:
    import logging
    from logging.handlers import SMTPHandler
    mail_handler = SMTPHandler('smtpout.secureserver.net',
                               'info@mydomain.com',
                               ADMINS, 'YourApplication Failed',
                               credentials=('info@mydomain.com','***'),
                               port=25)
    mail_handler.setLevel(logging.ERROR)
    app.logger.addHandler(mail_handler)

I'm also a bit confused by this line from the documentation:

If your mail server requires credentials, these can also be provided.

My server is not acting as a "mail server". What credentials should I be providing? My email is hosted at GoDaddy.

kaoscify
  • 1,743
  • 7
  • 37
  • 74

2 Answers2

7

You need to add the credentials for your email (username and password) like this:

mail_handler = SMTPHandler(mailhost=('smtpout.secureserver.net',25),
                           fromaddr='info@mydomain.com',
                           toaddrs=ADMINS, subject='YourApplication Failed',
                           credentials=('mail_username','mail_password'))

In essence you need to login into your mail account (from godaddy) to be able to send emails. The IP used needs to be the IP provided by godaddy for the STMP service (I believe it is smtpout.secureserver.net) and the port without SSL is one of 25, 80, 3535 if you are using SSL the port is 465.

Hope it helps!

EDIT: Since it still doesn't work when it should I'm adding a full minimal source code to test it, this is the quickstart minimal hello word example modified to send emails when an error occurs and to always fail (it will send an email every time you access the page), fully tested on godaddy (us):

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    raise Exception
    #return 'Hello World!'

if __name__ == '__main__':
    ADMINS = ['admin@mydomain.com']
    if not app.debug:
        import logging
        from logging.handlers import SMTPHandler
        mail_handler = SMTPHandler(mailhost=('smtpout.secureserver.net',25),
                           fromaddr='admin@mydomain.com',
                           toaddrs=ADMINS, subject='YourApplication Failed',
                           credentials=('admin@mydomain.com','mypassword'))
        mail_handler.setLevel(logging.ERROR)
        app.logger.addHandler(mail_handler)
    app.run()

It is important tho that you need to check the actual smtp server you need to use. When you log into godaddy click the email admin button (the button on email workspace) there go to the top menu TOOLS -> SERVER FUNCTIONS . After that select your domain and in the last row (SMTP) you should see a domain like the one I provided for the smtp outgoing access, in my case I have different ones for different domains:

smtpout.asia.secureserver.net
smtpout.secureserver.net

Find the one you need to use and modify my sample code, you should receive the emails instantly on the web interface of your godaddy email.

Once you have the right server and use your credentials you should receive an email like this one when running the app:

Exception on / [GET]
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\flask\app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python27\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python27\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "hello.py", line 6, in hello_world
raise Exception
Exception
Sergio Ayestarán
  • 5,590
  • 4
  • 38
  • 62
  • This makes sense, thank you. I have the modifications but unfortunately still not seeing any emails in my inbox upon errors. I edited my answer above with your suggestions. I added `port` after `credentials`. I have the logging module installed. – kaoscify Dec 14 '15 at 20:03
  • to setup the port you need to use mailhost=('smtpout.secureserver.net',25) I'm editing the answer to clarify that. Perhaps you need to try to setup the smtp server using another client first to check if it works ok and then configure this. Also remember to double check addresses and ports using the info provided by godaddy, contact customer support if you don't know where to find it, just call them it is fast. – Sergio Ayestarán Dec 14 '15 at 20:08
  • Ok, thanks. I will look into it. But after the second line `info@mydomain.com`, it results in a syntax error. It says `non-keyword arg after keyword arg`. Just saw your edit after coming across this: http://stackoverflow.com/questions/8191721/smtphandler-in-pythons-logging-module-sending-emails-one-at-a-time-how-can-i-s – kaoscify Dec 14 '15 at 20:17
  • Yeah, it should be fixed now. You still need to verify the access to your smtp server on godaddy, try to do it if it is still not working – Sergio Ayestarán Dec 14 '15 at 20:20
  • Still no idea why it's not working. I'm creating and seeing 500 Internal Server errors, but those don't get emailed. Email settings for SMTP are fine too because I have tested it in another email client. Anyway, thanks for your help. Appreciate it. – kaoscify Dec 14 '15 at 20:48
  • I've added a full working and tested example for you to use, please make sure that app.debug is not set, If Flask has any problem connecting or sending the email you should receive an error on the console, for instance "error: [Errno 10061] No connection could be made because the target machine actively refused it", make sure it either works or you receive an error. – Sergio Ayestarán Dec 14 '15 at 21:38
  • Thank you for the example. It works! Will this also work for 500 Internal Server Errors or just Flask related errors? For example, if Flask can't request something from the database (500 server error). – kaoscify Dec 15 '15 at 17:03
  • It will work as you describe it, if there is any error it will send the email with the trace, in the example the "raise Exception" covers any unexpected error (disclaimer: if you have a "Try: ... Except: pass" it will not send an email when something goes wrong inside the try, but that's what you want if you have those lines in your code) – Sergio Ayestarán Dec 15 '15 at 17:37
0

One thing you should do is consider using Flask-Mail (https://pythonhosted.org/flask-mail/#configuring-flask-mail). It helps to organize the email process. Read this: (http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xi-email-support)

Assuming you don't have smtp service at your domain:

Re. credentials. Set up email forwarding at your domain registrar. Then set-up a gmail account or some other service to send email from. (https://webapps.stackexchange.com/questions/66228/add-new-alias-to-gmail-without-smtp-forwarding-only-address). (See answer by @John)

Then custom@yoursite.com gets sent to u@gmail.com. And you can then send mail from custom@yoursite.com via your gmail or other service (e.g. mailgun).

Community
  • 1
  • 1
wgwz
  • 2,642
  • 2
  • 23
  • 35