use LOG.exception instead of LOG.error to provide stacktrace

This commit is contained in:
Son NK 2020-07-17 12:59:07 +02:00
parent 7f29756230
commit 6437ee46e0
18 changed files with 43 additions and 39 deletions

View File

@ -147,7 +147,7 @@ def delete_alias(alias: Alias, user: User):
) )
db.session.commit() db.session.commit()
except IntegrityError: except IntegrityError:
LOG.error( LOG.exception(
"alias %s domain %s has been added before to DeletedAlias", "alias %s domain %s has been added before to DeletedAlias",
alias.email, alias.email,
alias.custom_domain_id, alias.custom_domain_id,
@ -158,5 +158,5 @@ def delete_alias(alias: Alias, user: User):
DeletedAlias.create(email=alias.email) DeletedAlias.create(email=alias.email)
db.session.commit() db.session.commit()
except IntegrityError: except IntegrityError:
LOG.error("alias %s has been added before to DeletedAlias", alias.email) LOG.exception("alias %s has been added before to DeletedAlias", alias.email)
db.session.rollback() db.session.rollback()

View File

@ -519,7 +519,7 @@ def verify_receipt(receipt_data, user, password) -> Optional[AppleSubscription]:
else: else:
# the same original_transaction_id has been used on another account # the same original_transaction_id has been used on another account
if AppleSubscription.get_by(original_transaction_id=original_transaction_id): if AppleSubscription.get_by(original_transaction_id=original_transaction_id):
LOG.error("Same Apple Sub has been used before, current user %s", user) LOG.exception("Same Apple Sub has been used before, current user %s", user)
return None return None
LOG.d( LOG.d(

View File

@ -144,7 +144,7 @@ def new_custom_alias_v2():
LOG.warning("Alias creation time expired for %s", user) LOG.warning("Alias creation time expired for %s", user)
return jsonify(error="Alias creation time is expired, please retry"), 412 return jsonify(error="Alias creation time is expired, please retry"), 412
except Exception: except Exception:
LOG.error("Alias suffix is tampered, user %s", user) LOG.exception("Alias suffix is tampered, user %s", user)
return jsonify(error="Tampered suffix"), 400 return jsonify(error="Tampered suffix"), 400
if not verify_prefix_suffix(user, alias_prefix, alias_suffix): if not verify_prefix_suffix(user, alias_prefix, alias_suffix):
@ -254,7 +254,7 @@ def new_custom_alias_v3():
LOG.warning("Alias creation time expired for %s", user) LOG.warning("Alias creation time expired for %s", user)
return jsonify(error="Alias creation time is expired, please retry"), 412 return jsonify(error="Alias creation time is expired, please retry"), 412
except Exception: except Exception:
LOG.error("Alias suffix is tampered, user %s", user) LOG.exception("Alias suffix is tampered, user %s", user)
return jsonify(error="Tampered suffix"), 400 return jsonify(error="Tampered suffix"), 400
if not verify_prefix_suffix(user, alias_prefix, alias_suffix): if not verify_prefix_suffix(user, alias_prefix, alias_suffix):

View File

@ -94,7 +94,7 @@ def fido():
) )
new_sign_count = webauthn_assertion_response.verify() new_sign_count = webauthn_assertion_response.verify()
except Exception as e: except Exception as e:
LOG.error(f"An error occurred in WebAuthn verification process: {e}") LOG.exception(f"An error occurred in WebAuthn verification process: {e}")
flash("Key verification failed.", "warning") flash("Key verification failed.", "warning")
# Trigger rate limiter # Trigger rate limiter
g.deduct_limit = True g.deduct_limit = True

View File

@ -75,7 +75,7 @@ def github_callback():
break break
if not email: if not email:
LOG.error(f"cannot get email for github user {github_user_data} {emails}") LOG.exception(f"cannot get email for github user {github_user_data} {emails}")
flash( flash(
"Cannot get a valid email from Github, please another way to login/sign up", "Cannot get a valid email from Github, please another way to login/sign up",
"error", "error",

View File

@ -94,7 +94,7 @@ def custom_alias():
flash("Alias creation time is expired, please retry", "warning") flash("Alias creation time is expired, please retry", "warning")
return redirect(url_for("dashboard.custom_alias")) return redirect(url_for("dashboard.custom_alias"))
except Exception: except Exception:
LOG.error("Alias suffix is tampered, user %s", current_user) LOG.exception("Alias suffix is tampered, user %s", current_user)
flash("Unknown error, refresh the page", "error") flash("Unknown error, refresh the page", "error")
return redirect(url_for("dashboard.custom_alias")) return redirect(url_for("dashboard.custom_alias"))
@ -181,20 +181,20 @@ def verify_prefix_suffix(user, alias_prefix, alias_suffix) -> bool:
alias_domain not in user_custom_domains alias_domain not in user_custom_domains
and alias_domain not in ALIAS_DOMAINS and alias_domain not in ALIAS_DOMAINS
): ):
LOG.error("wrong alias suffix %s, user %s", alias_suffix, user) LOG.exception("wrong alias suffix %s, user %s", alias_suffix, user)
return False return False
else: else:
if alias_domain not in user_custom_domains: if alias_domain not in user_custom_domains:
LOG.error("wrong alias suffix %s, user %s", alias_suffix, user) LOG.exception("wrong alias suffix %s, user %s", alias_suffix, user)
return False return False
else: else:
if not alias_suffix.startswith("."): if not alias_suffix.startswith("."):
LOG.error("User %s submits a wrong alias suffix %s", user, alias_suffix) LOG.exception("User %s submits a wrong alias suffix %s", user, alias_suffix)
return False return False
full_alias = alias_prefix + alias_suffix full_alias = alias_prefix + alias_suffix
if not email_belongs_to_alias_domains(full_alias): if not email_belongs_to_alias_domains(full_alias):
LOG.error( LOG.exception(
"Alias suffix should end with one of the alias domains %s", "Alias suffix should end with one of the alias domains %s",
user, user,
alias_suffix, alias_suffix,
@ -203,7 +203,7 @@ def verify_prefix_suffix(user, alias_prefix, alias_suffix) -> bool:
random_word_part = alias_suffix[1 : alias_suffix.find("@")] random_word_part = alias_suffix[1 : alias_suffix.find("@")]
if not word_exist(random_word_part): if not word_exist(random_word_part):
LOG.error( LOG.exception(
"alias suffix %s needs to start with a random word, user %s", "alias suffix %s needs to start with a random word, user %s",
alias_suffix, alias_suffix,
user, user,

View File

@ -56,7 +56,7 @@ def fido_setup():
try: try:
fido_credential = fido_reg_response.verify() fido_credential = fido_reg_response.verify()
except Exception as e: except Exception as e:
LOG.error(f"An error occurred in WebAuthn registration process: {e}") LOG.exception(f"An error occurred in WebAuthn registration process: {e}")
flash("Key registration failed.", "warning") flash("Key registration failed.", "warning")
return redirect(url_for("dashboard.index")) return redirect(url_for("dashboard.index"))

View File

@ -179,7 +179,7 @@ def setting():
custom_domain.user_id != current_user.id custom_domain.user_id != current_user.id
or not custom_domain.verified or not custom_domain.verified
): ):
LOG.error( LOG.exception(
"%s cannot use domain %s", current_user, default_domain "%s cannot use domain %s", current_user, default_domain
) )
else: else:

View File

@ -489,7 +489,7 @@ class User(db.Model, ModelMixin, UserMixin):
or not custom_domain.verified or not custom_domain.verified
or custom_domain.user_id != self.id or custom_domain.user_id != self.id
): ):
LOG.error("Problem with %s default random alias domain", self) LOG.exception("Problem with %s default random alias domain", self)
return FIRST_ALIAS_DOMAIN return FIRST_ALIAS_DOMAIN
return custom_domain.domain return custom_domain.domain
@ -498,7 +498,7 @@ class User(db.Model, ModelMixin, UserMixin):
public_domain = PublicDomain.get(self.default_random_alias_public_domain_id) public_domain = PublicDomain.get(self.default_random_alias_public_domain_id)
# sanity check # sanity check
if not public_domain: if not public_domain:
LOG.error("Problem with %s public random alias domain", self) LOG.exception("Problem with %s public random alias domain", self)
return FIRST_ALIAS_DOMAIN return FIRST_ALIAS_DOMAIN
return public_domain.domain return public_domain.domain
@ -1410,7 +1410,7 @@ class Directory(db.Model, ModelMixin):
db.session.commit() db.session.commit()
# this can happen when a previously deleted alias is re-created via catch-all or directory feature # this can happen when a previously deleted alias is re-created via catch-all or directory feature
except IntegrityError: except IntegrityError:
LOG.error("Some aliases have been added before to DeletedAlias") LOG.exception("Some aliases have been added before to DeletedAlias")
db.session.rollback() db.session.rollback()
cls.query.filter(cls.id == obj_id).delete() cls.query.filter(cls.id == obj_id).delete()
@ -1480,7 +1480,7 @@ class Mailbox(db.Model, ModelMixin):
db.session.commit() db.session.commit()
# this can happen when a previously deleted alias is re-created via catch-all or directory feature # this can happen when a previously deleted alias is re-created via catch-all or directory feature
except IntegrityError: except IntegrityError:
LOG.error("Some aliases have been added before to DeletedAlias") LOG.exception("Some aliases have been added before to DeletedAlias")
db.session.rollback() db.session.rollback()
cls.query.filter(cls.id == obj_id).delete() cls.query.filter(cls.id == obj_id).delete()

View File

@ -160,7 +160,7 @@ def authorize():
flash("Alias creation time is expired, please retry", "warning") flash("Alias creation time is expired, please retry", "warning")
return redirect(request.url) return redirect(request.url)
except Exception: except Exception:
LOG.error("Alias suffix is tampered, user %s", current_user) LOG.exception("Alias suffix is tampered, user %s", current_user)
flash("Unknown error, refresh the page", "error") flash("Unknown error, refresh the page", "error")
return redirect(request.url) return redirect(request.url)
@ -178,7 +178,7 @@ def authorize():
or DeletedAlias.get_by(email=full_alias) or DeletedAlias.get_by(email=full_alias)
or DomainDeletedAlias.get_by(email=full_alias) or DomainDeletedAlias.get_by(email=full_alias)
): ):
LOG.error("alias %s already used, very rare!", full_alias) LOG.exception("alias %s already used, very rare!", full_alias)
flash(f"Alias {full_alias} already used", "error") flash(f"Alias {full_alias} already used", "error")
return redirect(request.url) return redirect(request.url)
else: else:

View File

@ -71,7 +71,7 @@ def cancel_subscription(subscription_id: int) -> bool:
) )
res = r.json() res = r.json()
if not res["success"]: if not res["success"]:
LOG.error( LOG.exception(
f"cannot cancel subscription {subscription_id}, paddle response: {res}" f"cannot cancel subscription {subscription_id}, paddle response: {res}"
) )
@ -90,7 +90,7 @@ def change_plan(subscription_id: int, plan_id) -> bool:
) )
res = r.json() res = r.json()
if not res["success"]: if not res["success"]:
LOG.error( LOG.exception(
f"cannot change subscription {subscription_id} to {plan_id}, paddle response: {res}" f"cannot change subscription {subscription_id} to {plan_id}, paddle response: {res}"
) )

View File

@ -39,7 +39,7 @@ def encrypt_file(data: BytesIO, fingerprint: str) -> str:
# todo # todo
if mem_usage > 300: if mem_usage > 300:
LOG.error("Force exit") LOG.exception("Force exit")
hard_exit() hard_exit()
r = gpg.encrypt_file(data, fingerprint, always_trust=True) r = gpg.encrypt_file(data, fingerprint, always_trust=True)

View File

@ -282,7 +282,7 @@ def sanity_check():
mailbox.nb_failed_checks += 1 mailbox.nb_failed_checks += 1
# alert if too much fail # alert if too much fail
if mailbox.nb_failed_checks > 10: if mailbox.nb_failed_checks > 10:
log_func = LOG.error log_func = LOG.exception
else: else:
log_func = LOG.warning log_func = LOG.warning
@ -299,11 +299,11 @@ def sanity_check():
for user in User.filter_by(activated=True).all(): for user in User.filter_by(activated=True).all():
if user.email.lower() != user.email: if user.email.lower() != user.email:
LOG.error("%s does not have lowercase email", user) LOG.exception("%s does not have lowercase email", user)
for mailbox in Mailbox.filter_by(verified=True).all(): for mailbox in Mailbox.filter_by(verified=True).all():
if mailbox.email.lower() != mailbox.email: if mailbox.email.lower() != mailbox.email:
LOG.error("%s does not have lowercase email", mailbox) LOG.exception("%s does not have lowercase email", mailbox)
LOG.d("Finish sanity check") LOG.d("Finish sanity check")

View File

@ -138,7 +138,7 @@ def get_or_create_contact(
LOG.warning("From header is empty, parse mail_from %s %s", mail_from, alias) LOG.warning("From header is empty, parse mail_from %s %s", mail_from, alias)
contact_name, contact_email = parseaddr_unicode(mail_from) contact_name, contact_email = parseaddr_unicode(mail_from)
if not contact_email: if not contact_email:
LOG.error( LOG.exception(
"Cannot parse contact from from_header:%s, mail_from:%s", "Cannot parse contact from from_header:%s, mail_from:%s",
contact_from_header, contact_from_header,
mail_from, mail_from,
@ -413,7 +413,7 @@ def forward_email_to_mailbox(
# sanity check: make sure mailbox is not actually an alias # sanity check: make sure mailbox is not actually an alias
if get_email_domain_part(alias.email) == get_email_domain_part(mailbox.email): if get_email_domain_part(alias.email) == get_email_domain_part(mailbox.email):
LOG.error( LOG.exception(
"Mailbox has the same domain as alias. %s -> %s -> %s", "Mailbox has the same domain as alias. %s -> %s -> %s",
contact, contact,
alias, alias,
@ -436,7 +436,7 @@ def forward_email_to_mailbox(
try: try:
msg = prepare_pgp_message(msg, mailbox.pgp_finger_print) msg = prepare_pgp_message(msg, mailbox.pgp_finger_print)
except PGPException: except PGPException:
LOG.error( LOG.exception(
"Cannot encrypt message %s -> %s. %s %s", contact, alias, mailbox, user "Cannot encrypt message %s -> %s. %s %s", contact, alias, mailbox, user
) )
# so the client can retry later # so the client can retry later
@ -630,7 +630,7 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, str
try: try:
msg = prepare_pgp_message(msg, contact.pgp_finger_print) msg = prepare_pgp_message(msg, contact.pgp_finger_print)
except PGPException: except PGPException:
LOG.error( LOG.exception(
"Cannot encrypt message %s -> %s. %s %s", alias, contact, mailbox, user "Cannot encrypt message %s -> %s. %s %s", alias, contact, mailbox, user
) )
# so the client can retry later # so the client can retry later
@ -645,7 +645,7 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, str
envelope.rcpt_options, envelope.rcpt_options,
) )
except Exception: except Exception:
LOG.error("Cannot send email from %s to %s", alias, contact) LOG.exception("Cannot send email from %s to %s", alias, contact)
send_email( send_email(
mailbox.email, mailbox.email,
f"Email cannot be sent to {contact.email} from {alias.email}", f"Email cannot be sent to {contact.email} from {alias.email}",
@ -685,7 +685,7 @@ def spf_pass(
try: try:
r = spf.check2(i=ip, s=envelope.mail_from.lower(), h=None) r = spf.check2(i=ip, s=envelope.mail_from.lower(), h=None)
except Exception: except Exception:
LOG.error("SPF error, mailbox %s, ip %s", mailbox.email, ip) LOG.exception("SPF error, mailbox %s, ip %s", mailbox.email, ip)
else: else:
# TODO: Handle temperr case (e.g. dns timeout) # TODO: Handle temperr case (e.g. dns timeout)
# only an absolute pass, or no SPF policy at all is 'valid' # only an absolute pass, or no SPF policy at all is 'valid'
@ -824,7 +824,7 @@ def handle_bounce(contact: Contact, alias: Alias, msg: Message, user: User):
mailbox_id = int(orig_msg[_MAILBOX_ID_HEADER]) mailbox_id = int(orig_msg[_MAILBOX_ID_HEADER])
mailbox = Mailbox.get(mailbox_id) mailbox = Mailbox.get(mailbox_id)
if not mailbox or mailbox.user_id != user.id: if not mailbox or mailbox.user_id != user.id:
LOG.error( LOG.exception(
"Tampered message mailbox_id %s, %s, %s, %s %s", "Tampered message mailbox_id %s, %s, %s, %s %s",
mailbox_id, mailbox_id,
user, user,

View File

@ -15,7 +15,9 @@ def load_pgp_public_keys():
# sanity check # sanity check
if fingerprint != mailbox.pgp_finger_print: if fingerprint != mailbox.pgp_finger_print:
LOG.error("fingerprint %s different for mailbox %s", fingerprint, mailbox) LOG.exception(
"fingerprint %s different for mailbox %s", fingerprint, mailbox
)
mailbox.pgp_finger_print = fingerprint mailbox.pgp_finger_print = fingerprint
db.session.commit() db.session.commit()
@ -25,7 +27,9 @@ def load_pgp_public_keys():
# sanity check # sanity check
if fingerprint != contact.pgp_finger_print: if fingerprint != contact.pgp_finger_print:
LOG.error("fingerprint %s different for contact %s", fingerprint, contact) LOG.exception(
"fingerprint %s different for contact %s", fingerprint, contact
)
contact.pgp_finger_print = fingerprint contact.pgp_finger_print = fingerprint
db.session.commit() db.session.commit()

View File

@ -130,6 +130,6 @@ if __name__ == "__main__":
onboarding_browser_extension(user) onboarding_browser_extension(user)
else: else:
LOG.error("Unknown job name %s", job.name) LOG.exception("Unknown job name %s", job.name)
time.sleep(10) time.sleep(10)

View File

@ -458,7 +458,7 @@ def setup_paddle_callback(app: Flask):
# make sure the request comes from Paddle # make sure the request comes from Paddle
if not paddle_utils.verify_incoming_request(dict(request.form)): if not paddle_utils.verify_incoming_request(dict(request.form)):
LOG.error( LOG.exception(
"request not coming from paddle. Request data:%s", dict(request.form) "request not coming from paddle. Request data:%s", dict(request.form)
) )
return "KO", 400 return "KO", 400

View File

@ -142,7 +142,7 @@ def disable_mailbox(mailbox_id):
email_msg.replace("\n", "<br>"), email_msg.replace("\n", "<br>"),
) )
except Exception: except Exception:
LOG.error("Cannot send disable mailbox email to %s", mailbox.user) LOG.exception("Cannot send disable mailbox email to %s", mailbox.user)
app = create_app() app = create_app()