2

I'm trying to display an error if there is an exception in my asynchronous send_email function but even after an exception is occurred in the background thread the data still gets stored in the database. The except block never gets executed. I'm trying to prevent the database commit and redirect to a page with an error message

send_email function file

from threading import Thread
from flask import current_app,render_template,flash
from flask_mail import Message
from feedback import mail


def send_async_email(app, msg):
    try:
        with app.app_context():
            mail.send(msg)
    except:
        raise Exception("Exception occurred in Mail")
        return False

def send_email(to,subject,template,**kwargs):
    app = current_app._get_current_object()
    msg=Message(current_app.config['MAIL_SUBJECT_PREFIX'] + subject,
    sender=current_app.config['MAIL_SENDER'],recipients=[to])
    msg.body=render_template(template +'.txt',**kwargs)
    msg.html=render_template(template +'.html',**kwargs)
    try:
        thr = Thread(target=send_async_email, args=[app, msg])
        thr.start()
        return thr
    except:
        raise Exception("Error occured")

views.py

@home.route('/register',methods=["GET","POST"])
def register():
    # form=LoginForm()
    form=LoginForm(prefix="login")
    form1=RegisterForm(prefix="register")
    print(form1.errors)
    if form1.validate_on_submit():

        users=Users(email=form1.email.data.strip())
        users.set_password(form1.password.data.strip())
        organization=Organization(organization_name=form1.org_name.data.strip())
        organization.userorg.append(users)
        db.session.add(users)
        db.session.add(organization)
        db.session.flush()
        token=users.generate_confirmation_token()
        try:
            print("INSIDE TRY BLOCK")
            email=send_email(users.email,'Confirm your account','email/confirm_email',user=users,token=token)
        except Exception as e:
            print("INSIDE Exception BLOCK")
            print(e)
            flash("Errors","danger")
            db.session.rollback()
            return redirect(url_for('home.home_view'))

        db.session.commit()
        flash("A confirmation email has been sent")
        return redirect(url_for('home.home_view'))


    return render_template('home/landing-semi.html',form=form,form1=form1)

Errors recieved

 raise SMTPSenderRefused(code, resp, from_addr)
smtplib.SMTPSenderRefused: (530, b'5.5.1 Authentication Required. Learn more at\n5.5.1  https://support.google.com/mail/?p=WantAuthError g10-v6sm7818697pfi.148 - gsmtp', '=?utf-8?q?Osfapp_Admin?= <lmnography@gmail.com>')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib64/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/leon/Leon/Projects/fmsappv/feedback/modules/utilties.py", line 12, in send_async_email
    raise Exception("Exception occurred in Mail")
Exception: Exception occurred in Mail
Leon N
  • 184
  • 2
  • 24
  • As it discussed [here](https://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python), exceptions happened in a separate thread are not propagated to the current thread and you should find another tools to notify your `register()` about errors. – Fine Jun 28 '18 at 16:04
  • I've never used threading, but all the solutions I found had exception handling within their threads. Mine doesn't seem to work. Is there a solution what tools do you suggest? – Leon N Jun 28 '18 at 16:50

0 Answers0