From 6437ee46e099fa46c54d4f378e050f89ee3ac5ec Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Fri, 17 Jul 2020 12:59:07 +0200 Subject: [PATCH] use LOG.exception instead of LOG.error to provide stacktrace --- app/alias_utils.py | 4 ++-- app/api/views/apple.py | 2 +- app/api/views/new_custom_alias.py | 4 ++-- app/auth/views/fido.py | 2 +- app/auth/views/github.py | 2 +- app/dashboard/views/custom_alias.py | 12 ++++++------ app/dashboard/views/fido_setup.py | 2 +- app/dashboard/views/setting.py | 2 +- app/models.py | 8 ++++---- app/oauth/views/authorize.py | 4 ++-- app/paddle_utils.py | 4 ++-- app/pgp_utils.py | 2 +- cron.py | 6 +++--- email_handler.py | 14 +++++++------- init_app.py | 8 ++++++-- job_runner.py | 2 +- server.py | 2 +- shell.py | 2 +- 18 files changed, 43 insertions(+), 39 deletions(-) diff --git a/app/alias_utils.py b/app/alias_utils.py index 3fe21748..1a4f4162 100644 --- a/app/alias_utils.py +++ b/app/alias_utils.py @@ -147,7 +147,7 @@ def delete_alias(alias: Alias, user: User): ) db.session.commit() except IntegrityError: - LOG.error( + LOG.exception( "alias %s domain %s has been added before to DeletedAlias", alias.email, alias.custom_domain_id, @@ -158,5 +158,5 @@ def delete_alias(alias: Alias, user: User): DeletedAlias.create(email=alias.email) db.session.commit() 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() diff --git a/app/api/views/apple.py b/app/api/views/apple.py index 4aa8518d..9cee685f 100644 --- a/app/api/views/apple.py +++ b/app/api/views/apple.py @@ -519,7 +519,7 @@ def verify_receipt(receipt_data, user, password) -> Optional[AppleSubscription]: else: # the same original_transaction_id has been used on another account 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 LOG.d( diff --git a/app/api/views/new_custom_alias.py b/app/api/views/new_custom_alias.py index 7f058303..2a12583e 100644 --- a/app/api/views/new_custom_alias.py +++ b/app/api/views/new_custom_alias.py @@ -144,7 +144,7 @@ def new_custom_alias_v2(): LOG.warning("Alias creation time expired for %s", user) return jsonify(error="Alias creation time is expired, please retry"), 412 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 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) return jsonify(error="Alias creation time is expired, please retry"), 412 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 if not verify_prefix_suffix(user, alias_prefix, alias_suffix): diff --git a/app/auth/views/fido.py b/app/auth/views/fido.py index 80751cfd..579c1bc3 100644 --- a/app/auth/views/fido.py +++ b/app/auth/views/fido.py @@ -94,7 +94,7 @@ def fido(): ) new_sign_count = webauthn_assertion_response.verify() 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") # Trigger rate limiter g.deduct_limit = True diff --git a/app/auth/views/github.py b/app/auth/views/github.py index 2324161b..7b2a684f 100644 --- a/app/auth/views/github.py +++ b/app/auth/views/github.py @@ -75,7 +75,7 @@ def github_callback(): break 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( "Cannot get a valid email from Github, please another way to login/sign up", "error", diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index 8b92c10c..a3b61903 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -94,7 +94,7 @@ def custom_alias(): flash("Alias creation time is expired, please retry", "warning") return redirect(url_for("dashboard.custom_alias")) 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") 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 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 else: 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 else: 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 full_alias = alias_prefix + alias_suffix if not email_belongs_to_alias_domains(full_alias): - LOG.error( + LOG.exception( "Alias suffix should end with one of the alias domains %s", user, 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("@")] 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, user, diff --git a/app/dashboard/views/fido_setup.py b/app/dashboard/views/fido_setup.py index b77eda41..e7b8f63e 100644 --- a/app/dashboard/views/fido_setup.py +++ b/app/dashboard/views/fido_setup.py @@ -56,7 +56,7 @@ def fido_setup(): try: fido_credential = fido_reg_response.verify() 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") return redirect(url_for("dashboard.index")) diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index 1300274a..4a44dab5 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -179,7 +179,7 @@ def setting(): custom_domain.user_id != current_user.id or not custom_domain.verified ): - LOG.error( + LOG.exception( "%s cannot use domain %s", current_user, default_domain ) else: diff --git a/app/models.py b/app/models.py index 7d7b15e4..9471bc88 100644 --- a/app/models.py +++ b/app/models.py @@ -489,7 +489,7 @@ class User(db.Model, ModelMixin, UserMixin): or not custom_domain.verified 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 custom_domain.domain @@ -498,7 +498,7 @@ class User(db.Model, ModelMixin, UserMixin): public_domain = PublicDomain.get(self.default_random_alias_public_domain_id) # sanity check 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 public_domain.domain @@ -1410,7 +1410,7 @@ class Directory(db.Model, ModelMixin): db.session.commit() # this can happen when a previously deleted alias is re-created via catch-all or directory feature 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() cls.query.filter(cls.id == obj_id).delete() @@ -1480,7 +1480,7 @@ class Mailbox(db.Model, ModelMixin): db.session.commit() # this can happen when a previously deleted alias is re-created via catch-all or directory feature 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() cls.query.filter(cls.id == obj_id).delete() diff --git a/app/oauth/views/authorize.py b/app/oauth/views/authorize.py index af608e3e..8b6c5440 100644 --- a/app/oauth/views/authorize.py +++ b/app/oauth/views/authorize.py @@ -160,7 +160,7 @@ def authorize(): flash("Alias creation time is expired, please retry", "warning") return redirect(request.url) 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") return redirect(request.url) @@ -178,7 +178,7 @@ def authorize(): or DeletedAlias.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") return redirect(request.url) else: diff --git a/app/paddle_utils.py b/app/paddle_utils.py index cb782e90..ed953440 100644 --- a/app/paddle_utils.py +++ b/app/paddle_utils.py @@ -71,7 +71,7 @@ def cancel_subscription(subscription_id: int) -> bool: ) res = r.json() if not res["success"]: - LOG.error( + LOG.exception( 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() if not res["success"]: - LOG.error( + LOG.exception( f"cannot change subscription {subscription_id} to {plan_id}, paddle response: {res}" ) diff --git a/app/pgp_utils.py b/app/pgp_utils.py index 47ac065d..4b64f48b 100644 --- a/app/pgp_utils.py +++ b/app/pgp_utils.py @@ -39,7 +39,7 @@ def encrypt_file(data: BytesIO, fingerprint: str) -> str: # todo if mem_usage > 300: - LOG.error("Force exit") + LOG.exception("Force exit") hard_exit() r = gpg.encrypt_file(data, fingerprint, always_trust=True) diff --git a/cron.py b/cron.py index 926843ad..649b1d6d 100644 --- a/cron.py +++ b/cron.py @@ -282,7 +282,7 @@ def sanity_check(): mailbox.nb_failed_checks += 1 # alert if too much fail if mailbox.nb_failed_checks > 10: - log_func = LOG.error + log_func = LOG.exception else: log_func = LOG.warning @@ -299,11 +299,11 @@ def sanity_check(): for user in User.filter_by(activated=True).all(): 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(): 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") diff --git a/email_handler.py b/email_handler.py index 2221991a..1b55bd37 100644 --- a/email_handler.py +++ b/email_handler.py @@ -138,7 +138,7 @@ def get_or_create_contact( LOG.warning("From header is empty, parse mail_from %s %s", mail_from, alias) contact_name, contact_email = parseaddr_unicode(mail_from) if not contact_email: - LOG.error( + LOG.exception( "Cannot parse contact from from_header:%s, mail_from:%s", contact_from_header, mail_from, @@ -413,7 +413,7 @@ def forward_email_to_mailbox( # sanity check: make sure mailbox is not actually an alias 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", contact, alias, @@ -436,7 +436,7 @@ def forward_email_to_mailbox( try: msg = prepare_pgp_message(msg, mailbox.pgp_finger_print) except PGPException: - LOG.error( + LOG.exception( "Cannot encrypt message %s -> %s. %s %s", contact, alias, mailbox, user ) # so the client can retry later @@ -630,7 +630,7 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, str try: msg = prepare_pgp_message(msg, contact.pgp_finger_print) except PGPException: - LOG.error( + LOG.exception( "Cannot encrypt message %s -> %s. %s %s", alias, contact, mailbox, user ) # 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, ) 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( mailbox.email, f"Email cannot be sent to {contact.email} from {alias.email}", @@ -685,7 +685,7 @@ def spf_pass( try: r = spf.check2(i=ip, s=envelope.mail_from.lower(), h=None) 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: # TODO: Handle temperr case (e.g. dns timeout) # 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 = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != user.id: - LOG.error( + LOG.exception( "Tampered message mailbox_id %s, %s, %s, %s %s", mailbox_id, user, diff --git a/init_app.py b/init_app.py index 81ac645d..c12d9d08 100644 --- a/init_app.py +++ b/init_app.py @@ -15,7 +15,9 @@ def load_pgp_public_keys(): # sanity check 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 db.session.commit() @@ -25,7 +27,9 @@ def load_pgp_public_keys(): # sanity check 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 db.session.commit() diff --git a/job_runner.py b/job_runner.py index b6971b59..8ec6582b 100644 --- a/job_runner.py +++ b/job_runner.py @@ -130,6 +130,6 @@ if __name__ == "__main__": onboarding_browser_extension(user) else: - LOG.error("Unknown job name %s", job.name) + LOG.exception("Unknown job name %s", job.name) time.sleep(10) diff --git a/server.py b/server.py index 76e38ee1..f28437f0 100644 --- a/server.py +++ b/server.py @@ -458,7 +458,7 @@ def setup_paddle_callback(app: Flask): # make sure the request comes from Paddle 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) ) return "KO", 400 diff --git a/shell.py b/shell.py index 8e5e8b43..bbed14b7 100644 --- a/shell.py +++ b/shell.py @@ -142,7 +142,7 @@ def disable_mailbox(mailbox_id): email_msg.replace("\n", "
"), ) 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()