From 0cf167c67a2d632bef6c6e4da3d886b658892021 Mon Sep 17 00:00:00 2001 From: Mathieu <923463-mathbou@users.noreply.gitlab.com> Date: Wed, 1 Feb 2023 00:48:22 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=94=8A=20no=20more=20silent=20excepti?= =?UTF-8?q?ons=20+=20more=20specific=20error=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- developer/bake_config.py | 3 +- hooks/get_current_login.py | 3 +- python/tank/api.py | 3 +- .../interactive_authentication.py | 3 +- python/tank/authentication/session_cache.py | 2 +- python/tank/commands/cache_yaml.py | 2 +- python/tank/commands/clone_configuration.py | 2 +- python/tank/commands/console_utils.py | 2 +- python/tank/commands/dump_config.py | 4 +- python/tank/commands/install.py | 4 +- python/tank/commands/misc.py | 8 ++-- python/tank/commands/move_pc.py | 6 +-- python/tank/commands/push_pc.py | 6 +-- python/tank/commands/setup_project.py | 4 +- python/tank/commands/switch.py | 2 +- .../tank/descriptor/io_descriptor/appstore.py | 2 +- python/tank/descriptor/io_descriptor/base.py | 3 +- .../descriptor/io_descriptor/downloadable.py | 8 ++-- python/tank/descriptor/io_descriptor/git.py | 7 ++-- .../descriptor/io_descriptor/git_branch.py | 9 +++-- .../tank/descriptor/io_descriptor/git_tag.py | 7 ++-- python/tank/folder/folder_types/listfield.py | 6 +-- python/tank/hook.py | 4 +- python/tank/log.py | 6 +-- python/tank/pipelineconfig_utils.py | 2 + python/tank/platform/bundle.py | 3 +- python/tank/platform/qt/tankqdialog.py | 4 +- python/tank/util/login.py | 6 ++- python/tank/util/metrics.py | 37 +++++++++++-------- python/tank/util/pyside2_patcher.py | 6 ++- python/tank/util/qt_importer.py | 12 ++++-- python/tank/util/shotgun/publish_util.py | 3 +- setup.py | 20 +++++----- tests/platform_tests/test_application.py | 3 +- tests/python/tank_test/tank_test_base.py | 5 +-- 35 files changed, 115 insertions(+), 92 deletions(-) diff --git a/developer/bake_config.py b/developer/bake_config.py index 590cfb7524..abe7a8a77b 100644 --- a/developer/bake_config.py +++ b/developer/bake_config.py @@ -31,6 +31,7 @@ from tank.descriptor import create_descriptor, is_descriptor_version_missing from tank.descriptor.errors import TankDescriptorError from tank.bootstrap import constants as bootstrap_constants +from shotgun_api3 import ShotgunError import functools from utils import ( @@ -293,7 +294,7 @@ def main(): # make sure we are properly connected try: sg_connection.find_one("HumanUser", []) - except Exception as e: + except ShotgunError as e: logger.error("Could not communicate with ShotGrid: %s" % e) return 3 diff --git a/hooks/get_current_login.py b/hooks/get_current_login.py index 78870b5aec..9169c71ecd 100644 --- a/hooks/get_current_login.py +++ b/hooks/get_current_login.py @@ -54,5 +54,6 @@ def execute(self, **kwargs): pwd_entry = pwd.getpwuid(os.geteuid()) return pwd_entry[0] - except: + except Exception: + self.logger.debug("GetCurrentLogin hook failed.", exc_info=True) return None diff --git a/python/tank/api.py b/python/tank/api.py index a2cdc01782..429eacbca5 100644 --- a/python/tank/api.py +++ b/python/tank/api.py @@ -282,7 +282,8 @@ def documentation_url(self): data = str(data.get("documentation_url")) if data == "": data = None - except Exception: + except Exception as e: + log.debug("Cant get documentation url: %s" %e) data = None return data diff --git a/python/tank/authentication/interactive_authentication.py b/python/tank/authentication/interactive_authentication.py index 3e1df9f8b4..3207fd9233 100644 --- a/python/tank/authentication/interactive_authentication.py +++ b/python/tank/authentication/interactive_authentication.py @@ -68,7 +68,8 @@ def _get_current_os_user(): pwd_entry = pwd.getpwuid(os.geteuid()) return pwd_entry[0] - except: + except Exception as e: + logger.debug("Cant get current user: %s" %e) return None diff --git a/python/tank/authentication/session_cache.py b/python/tank/authentication/session_cache.py index d236f824b4..cf72c28899 100644 --- a/python/tank/authentication/session_cache.py +++ b/python/tank/authentication/session_cache.py @@ -645,6 +645,6 @@ def generate_session_token(hostname, login, password, http_proxy, auth_token=Non # If the error message is empty, like httplib.HTTPException, convert # the class name to a string if len(str(e)) == 0: - raise Exception("Unknown error: %s" % type(e).__name__) + raise type(e)("Unknown error: %s" % type(e).__name__) else: raise diff --git a/python/tank/commands/cache_yaml.py b/python/tank/commands/cache_yaml.py index b299f4c093..c653b7b0ab 100644 --- a/python/tank/commands/cache_yaml.py +++ b/python/tank/commands/cache_yaml.py @@ -86,7 +86,7 @@ def _run(self, log): try: fh = open(pickle_path, "wb") - except Exception as e: + except OSError as e: raise TankError("Unable to open '%s' for writing: %s" % (pickle_path, e)) try: diff --git a/python/tank/commands/clone_configuration.py b/python/tank/commands/clone_configuration.py index 12742daa1f..b576f1a047 100644 --- a/python/tank/commands/clone_configuration.py +++ b/python/tank/commands/clone_configuration.py @@ -280,7 +280,7 @@ def _do_clone( fh.write("# End of file.\n") fh.close() - except Exception as e: + except OSError as e: raise TankError("Could not create file system structure: %s" % e) # lastly, update the pipeline_configuration.yml file diff --git a/python/tank/commands/console_utils.py b/python/tank/commands/console_utils.py index 4aee97d8d0..9b18753c7d 100644 --- a/python/tank/commands/console_utils.py +++ b/python/tank/commands/console_utils.py @@ -228,7 +228,7 @@ def _get_configuration_recursive( param_name, answer, ) - except Exception as e: + except TankError as e: log.error("Validation failed: %s" % e) else: input_valid = True diff --git a/python/tank/commands/dump_config.py b/python/tank/commands/dump_config.py index f6eeaa86e3..02e11fc153 100644 --- a/python/tank/commands/dump_config.py +++ b/python/tank/commands/dump_config.py @@ -213,7 +213,7 @@ def _run(self, log, params): log.info( "Environment written to: %s" % (os.path.abspath(params["file"])) ) - except Exception as e: + except TankError as e: import traceback traceback.print_exc() @@ -244,7 +244,7 @@ def _get_file_handle(self, params): ) try: fh = open(path, "w") - except Exception as e: + except OSError as e: raise TankError( "Unable to open file: %s\n" " Error reported: %s" % (path, e) ) diff --git a/python/tank/commands/install.py b/python/tank/commands/install.py index ed5066b59c..d1be9c1036 100644 --- a/python/tank/commands/install.py +++ b/python/tank/commands/install.py @@ -226,7 +226,7 @@ def _run(self, log, env_name, engine_instance_name, app_name, preserve_yaml): env_name, writable=True ) env.set_yaml_preserve_mode(preserve_yaml) - except Exception as e: + except TankError as e: raise TankError( "Environment '%s' could not be loaded! Error reported: %s" % (env_name, e) @@ -528,7 +528,7 @@ def _run(self, log, env_name, engine_name, preserve_yaml): env_name, writable=True ) env.set_yaml_preserve_mode(preserve_yaml) - except Exception as e: + except TankError as e: raise TankError( "Environment '%s' could not be loaded! Error reported: %s" % (env_name, e) diff --git a/python/tank/commands/misc.py b/python/tank/commands/misc.py index 1174225965..4208d44df5 100644 --- a/python/tank/commands/misc.py +++ b/python/tank/commands/misc.py @@ -70,8 +70,8 @@ def _run(self, log): log.debug("Deleting cache file %s..." % full_path) try: os.remove(full_path) - except: - log.warning("Could not delete cache file '%s'!" % full_path) + except OSError as e: + log.warning("Could not delete cache file '%s'! // %s" % (full_path, e)) log.info("The SG menu cache has been cleared.") @@ -137,7 +137,7 @@ def run_interactive(self, log, args): readline.parse_and_bind("bind ^I rl_complete") else: readline.parse_and_bind("tab: complete") - except: - pass + except Exception as e: + msg.append(e) code.interact(banner="\n".join(msg), local=tk_locals) diff --git a/python/tank/commands/move_pc.py b/python/tank/commands/move_pc.py index c63b7274f1..60121b64f7 100644 --- a/python/tank/commands/move_pc.py +++ b/python/tank/commands/move_pc.py @@ -48,7 +48,7 @@ def _cleanup_old_location(self, log, path): log.debug("Removing %s..." % full_path) try: os.remove(full_path) - except Exception as e: + except OSError as e: log.warning( "Could not delete file %s. Error Reported: %s" % (full_path, e) @@ -68,7 +68,7 @@ def _cleanup_old_location(self, log, path): log.debug("Deleting folder %s..." % full_path) try: os.rmdir(full_path) - except Exception as e: + except OSError as e: log.warning( "Could not remove folder %s. Error Reported: %s" % (full_path, e) @@ -272,7 +272,7 @@ def run_interactive(self, log, args): fh.write("# End of file.\n") fh.close() - except Exception as e: + except OSError as e: raise TankError( "Could not copy configuration! This may be because of system " "permissions or system setup. This configuration will " diff --git a/python/tank/commands/push_pc.py b/python/tank/commands/push_pc.py index 49b2654e78..4275e3d14c 100644 --- a/python/tank/commands/push_pc.py +++ b/python/tank/commands/push_pc.py @@ -137,8 +137,8 @@ def run_interactive(self, log, args): raise TankError("Aborted by user.") try: target_pc_id = int(answer) - except: - raise TankError("Please enter a number!") + except ValueError as e: + raise TankError("Please enter a number! // %s" % e) self._run( log, @@ -230,7 +230,7 @@ def _run(self, log, target_id, use_symlink=False): for env_name in self.tk.pipeline_configuration.get_environments(): try: env = self.tk.pipeline_configuration.get_environment(env_name) - except Exception as e: + except TankError as e: raise TankError( "Failed to load environment %s," " run 'tank validate' for more details, got error: %s" diff --git a/python/tank/commands/setup_project.py b/python/tank/commands/setup_project.py index 0b19eda9f2..340de29b85 100644 --- a/python/tank/commands/setup_project.py +++ b/python/tank/commands/setup_project.py @@ -548,8 +548,8 @@ def _select_project(self, log, sg, show_initialized_projects): raise TankError("Aborted by user.") try: project_id = int(answer) - except: - raise TankError("Please enter a number!") + except ValueError as e: + raise TankError("Please enter a number! // %s" % e) if project_id not in [x["id"] for x in projs]: raise TankError("Id %d was not found in the list of projects!" % project_id) diff --git a/python/tank/commands/switch.py b/python/tank/commands/switch.py index dcfe5ce3bd..60fd2ea76d 100644 --- a/python/tank/commands/switch.py +++ b/python/tank/commands/switch.py @@ -143,7 +143,7 @@ def run_interactive(self, log, args): env_name, writable=True ) env.set_yaml_preserve_mode(preserve_yaml) - except Exception as e: + except TankError as e: raise TankError( "Environment '%s' could not be loaded! Error reported: %s" % (env_name, e) diff --git a/python/tank/descriptor/io_descriptor/appstore.py b/python/tank/descriptor/io_descriptor/appstore.py index 59fcad9d2a..c2949c436c 100644 --- a/python/tank/descriptor/io_descriptor/appstore.py +++ b/python/tank/descriptor/io_descriptor/appstore.py @@ -399,7 +399,7 @@ def get_changelog(self): summary = sg_version_data.get("description") url = sg_version_data.get("sg_detailed_release_notes").get("url") except Exception: - pass + log.exception("Cant get changelog.") return (summary, url) def _download_local(self, destination_path): diff --git a/python/tank/descriptor/io_descriptor/base.py b/python/tank/descriptor/io_descriptor/base.py index f53e9d4237..f4fb962539 100644 --- a/python/tank/descriptor/io_descriptor/base.py +++ b/python/tank/descriptor/io_descriptor/base.py @@ -260,7 +260,8 @@ def _find_latest_tag_by_pattern(self, version_numbers, pattern): for version_num in version_numbers: try: version_split = list(map(int, version_num[1:].split("."))) - except Exception: + except Exception as e: + log.debug(e) # this git tag is not on the expected form vX.Y.Z where X Y and Z are ints. skip. continue diff --git a/python/tank/descriptor/io_descriptor/downloadable.py b/python/tank/descriptor/io_descriptor/downloadable.py index 4580c0788c..1ec0a8ec1d 100644 --- a/python/tank/descriptor/io_descriptor/downloadable.py +++ b/python/tank/descriptor/io_descriptor/downloadable.py @@ -91,7 +91,7 @@ def open_write_location(self): target_parent = os.path.dirname(target) try: filesystem.ensure_folder_exists(target_parent) - except Exception as e: + except OSError as e: if not os.path.exists(target_parent): log.error("Failed to create directory %s: %s" % (target_parent, e)) raise TankDescriptorIOError( @@ -104,7 +104,7 @@ def open_write_location(self): # download completed without issue. Now create settings folder metadata_folder = self._get_metadata_folder(temporary_path) filesystem.ensure_folder_exists(metadata_folder) - except Exception as e: + except OSError as e: # something went wrong during the download, remove the temporary files. log.error( "Failed to download into path %s: %s. Attempting to remove it." @@ -141,7 +141,7 @@ def open_write_location(self): % target ) - except Exception as e: + except OSError as e: # if the target path already exists, this means someone else is either # moving things right now or have moved it already, so we are ok. @@ -188,7 +188,7 @@ def open_write_location(self): filesystem.safe_delete_folder(temporary_path) move_succeeded = True - except Exception as e: + except OSError as e: # something during the copy went wrong. Attempt to roll back the target # so we aren't left with any corrupt bundle cache items. if os.path.exists(target): diff --git a/python/tank/descriptor/io_descriptor/git.py b/python/tank/descriptor/io_descriptor/git.py index 8b60f6d17f..91ac082e28 100644 --- a/python/tank/descriptor/io_descriptor/git.py +++ b/python/tank/descriptor/io_descriptor/git.py @@ -34,7 +34,8 @@ def _can_hide_terminal(): subprocess.STARTF_USESHOWWINDOW subprocess.SW_HIDE return True - except Exception: + except AttributeError as e: + log.debug("Terminal cant be hidden: %s" % e) return False @@ -131,7 +132,7 @@ def _clone_then_execute_git_commands( log.debug("Checking that git exists and can be executed...") try: output = _check_output(["git", "--version"]) - except: + except SubprocessCalledProcessError: log.exception("Unexpected error:") raise TankGitError( "Cannot execute the 'git' command. Please make sure that git is " @@ -291,7 +292,7 @@ def has_remote_access(self): # clone repo into temp folder self._tmp_clone_then_execute_git_commands([], depth=1) log.debug("...connection established") - except Exception as e: + except (OSError, SubprocessCalledProcessError) as e: log.debug("...could not establish connection: %s" % e) can_connect = False return can_connect diff --git a/python/tank/descriptor/io_descriptor/git_branch.py b/python/tank/descriptor/io_descriptor/git_branch.py index a11db88f8b..943a8ea11f 100644 --- a/python/tank/descriptor/io_descriptor/git_branch.py +++ b/python/tank/descriptor/io_descriptor/git_branch.py @@ -10,11 +10,12 @@ import os import copy -from .git import IODescriptorGit, _check_output +from .git import IODescriptorGit, _check_output, TankGitError from ..errors import TankDescriptorError from ... import LogManager from tank_vendor import six +from ...util.process import SubprocessCalledProcessError log = LogManager.get_logger(__name__) @@ -119,7 +120,7 @@ def _is_latest_commit(self, version, branch): log.debug("Checking if the version is pointing to the latest commit...") try: output = _check_output(["git", "ls-remote", self._path, branch]) - except: + except SubprocessCalledProcessError: log.exception("Unexpected error:") raise TankGitError( "Cannot execute the 'git' command. Please make sure that git is " @@ -168,7 +169,7 @@ def _download_local(self, destination_path): ref=self._branch, is_latest_commit=is_latest_commit, ) - except Exception as e: + except (TankGitError, OSError, SubprocessCalledProcessError) as e: raise TankDescriptorError( "Could not download %s, branch %s, " "commit %s: %s" % (self._path, self._branch, self._version, e) @@ -215,7 +216,7 @@ def get_latest_version(self, constraint_pattern=None): ] git_hash = self._tmp_clone_then_execute_git_commands(commands) - except Exception as e: + except (TankGitError, OSError, SubprocessCalledProcessError) as e: raise TankDescriptorError( "Could not get latest commit for %s, " "branch %s: %s" % (self._path, self._branch, e) diff --git a/python/tank/descriptor/io_descriptor/git_tag.py b/python/tank/descriptor/io_descriptor/git_tag.py index c6a9f6ff19..996928bd25 100644 --- a/python/tank/descriptor/io_descriptor/git_tag.py +++ b/python/tank/descriptor/io_descriptor/git_tag.py @@ -11,11 +11,12 @@ import copy import re -from .git import IODescriptorGit +from .git import IODescriptorGit, TankGitError from ..errors import TankDescriptorError from ... import LogManager from tank_vendor import six +from ...util.process import SubprocessCalledProcessError log = LogManager.get_logger(__name__) @@ -145,7 +146,7 @@ def _download_local(self, destination_path): self._clone_then_execute_git_commands( destination_path, [], depth=1, ref=self._version ) - except Exception as e: + except (TankGitError, OSError, SubprocessCalledProcessError) as e: raise TankDescriptorError( "Could not download %s, " "tag %s: %s" % (self._path, self._version, e) ) @@ -222,7 +223,7 @@ def _fetch_tags(self): if m: git_tags.append(m.group(1)) - except Exception as e: + except (TankGitError, OSError, SubprocessCalledProcessError) as e: raise TankDescriptorError( "Could not get list of tags for %s: %s" % (self._path, e) ) diff --git a/python/tank/folder/folder_types/listfield.py b/python/tank/folder/folder_types/listfield.py index 5d3d9c3456..c7caaf111d 100644 --- a/python/tank/folder/folder_types/listfield.py +++ b/python/tank/folder/folder_types/listfield.py @@ -172,10 +172,10 @@ def _create_folders_impl(self, io_receiver, parent_path, sg_data): chunks = self._field_name.split(".") entity_type = chunks[1] field_name = chunks[2] - except: + except IndexError as e: msg = ( - "Folder creation error: Cannot resolve the field expression %s." - % self._field_name + "Folder creation error: Cannot resolve the field expression %s: %s" + % (self._field_name, e) ) raise TankError(msg) diff --git a/python/tank/hook.py b/python/tank/hook.py index 12b2502e75..01d6f5f66e 100644 --- a/python/tank/hook.py +++ b/python/tank/hook.py @@ -447,10 +447,10 @@ def some_method(self): try: engine = self.__parent.engine - except: + except Exception as e: raise TankError( "Cannot load framework %s for %r - it does not have a " - "valid engine property!" % (framework_instance_name, self.__parent) + "valid engine property! // %s" % (framework_instance_name, self.__parent, e) ) return framework.load_framework( diff --git a/python/tank/log.py b/python/tank/log.py index 65317cb624..c3bfe3848f 100644 --- a/python/tank/log.py +++ b/python/tank/log.py @@ -304,7 +304,7 @@ def doRollover(self): try: os.rename(self.baseFilename, temp_backup_name) - except: + except OSError: # It failed, so we'll simply append from now on. log.debug( "Cannot rotate log file '%s'. Logging will continue to this file, " @@ -319,7 +319,7 @@ def doRollover(self): # so doRollover can do its work. try: os.rename(temp_backup_name, self.baseFilename) - except: + except OSError: # For some reason we couldn't move the backup in its place. log.debug( "Unexpected issue while rotating log file '%s'. Logging will continue to this file, " @@ -344,7 +344,7 @@ def doRollover(self): # disable rollover and append to the current log. try: RotatingFileHandler.doRollover(self) - except: + except OSError: # Something probably failed trying to rollover the backups, # since the code above proved that in theory the main log file # should be renamable. In any case, we didn't succeed in renaming, diff --git a/python/tank/pipelineconfig_utils.py b/python/tank/pipelineconfig_utils.py index 0ab344816d..6838fc4b6b 100644 --- a/python/tank/pipelineconfig_utils.py +++ b/python/tank/pipelineconfig_utils.py @@ -260,6 +260,7 @@ def get_core_path_for_config(pipeline_config_path): studio_folder = os.path.normpath(studio_folder) return studio_folder except Exception: + logger.debug("Cant get core path for config %s" % pipeline_config_path, exc_info=True) return None @@ -472,6 +473,7 @@ def _get_version_from_manifest(info_yml_path): data = yaml_cache.g_yaml_cache.get(info_yml_path, deepcopy_data=False) or {} data = str(data.get("version", "unknown")) except Exception: + logger.debug("Cant get version from manifest %s" % info_yml_path, exc_info=True) data = "unknown" return data diff --git a/python/tank/platform/bundle.py b/python/tank/platform/bundle.py index 86576c0925..5b4f8cb904 100644 --- a/python/tank/platform/bundle.py +++ b/python/tank/platform/bundle.py @@ -1065,7 +1065,8 @@ def _get_engine_name(self): # therefore get an error. try: engine_name = self.engine.name - except: + except AttributeError as e: + self.logger.debug("Cant get engine name: %s" % e) engine_name = None return engine_name diff --git a/python/tank/platform/qt/tankqdialog.py b/python/tank/platform/qt/tankqdialog.py index e07bf5479d..60cd152d59 100644 --- a/python/tank/platform/qt/tankqdialog.py +++ b/python/tank/platform/qt/tankqdialog.py @@ -360,8 +360,8 @@ def _format_context_property(p, show_type=False): context_info += "You are currently running in the %s environment." % ( self._bundle.engine.environment["name"] ) - except: - pass + except Exception as e: + context_info += "Cant get current engine environment name: %s" % e self.ui.app_work_area_info.setText(context_info) diff --git a/python/tank/util/login.py b/python/tank/util/login.py index 442cb3776d..0a4894dc08 100644 --- a/python/tank/util/login.py +++ b/python/tank/util/login.py @@ -14,11 +14,12 @@ """ import os -import sys from . import constants from .platforms import is_windows +from .. import LogManager +log = LogManager.get_logger(__name__) def get_login_name(): """ @@ -34,7 +35,8 @@ def get_login_name(): pwd_entry = pwd.getpwuid(os.geteuid()) return pwd_entry[0] - except: + except Exception as e: + log.debug("Cant get login name: %s" % e) return None diff --git a/python/tank/util/metrics.py b/python/tank/util/metrics.py index 2662788143..403ef65563 100644 --- a/python/tank/util/metrics.py +++ b/python/tank/util/metrics.py @@ -30,9 +30,12 @@ # use api json to cover py 2.5 from tank_vendor import shotgun_api3, six +from .. import LogManager json = shotgun_api3.shotgun.json +log = LogManager.get_logger(__name__) + # From Python 3.8 and later, platform.linux_distribution has been removed, # so we need something else. Fortunately, the functionality was preserved # as the distro package on pypi.org. Given that the functionality is @@ -80,7 +83,8 @@ def get_darwin_version(cls): # For macOS / OSX we keep only the Major.minor os_version = re.findall(r"\d*\.\d*", raw_version_str)[0] - except: + except Exception: + log.debug("Cant get Darwin version.", exc_info=True) pass return os_version @@ -104,7 +108,9 @@ def get_linux_version(cls): major_version_str = re.findall(r"\d*", raw_version_str)[0] os_version = "%s %s" % (distribution, major_version_str) - except: + + except Exception: + log.debug("Cant get Linux version.", exc_info=True) pass return os_version @@ -124,7 +130,8 @@ def get_windows_version(cls): # as it returns a friendly name e.g: XP, 7, 10 etc. os_version = platform.release() - except: + except Exception: + log.debug("Cant get Windows version.", exc_info=True) pass return os_version @@ -169,9 +176,10 @@ def get_platform_info(cls): else: os_info["OS"] = "Unsupported system: (%s)" % (system) - except: + + except Exception: # On any exception we fallback to default value - pass + log.debug("Cant get platform info.", exc_info=True) # Cache information to save on subsequent calls cls.__cached_platform_info = os_info @@ -251,8 +259,8 @@ def log(self, metric, log_once=False): # remember that we've logged this one already self.__logged_metrics.add(metric_identifier) - except: - pass + except Exception as e: + log.debug(e) finally: self._lock.release() @@ -283,8 +291,8 @@ def get_metrics(self, count=None): # would be nice to be able to pop N from deque. oh well. metrics = [self._queue.popleft() for i in range(0, count)] - except: - pass + except Exception as e: + log.debug(e) finally: self._lock.release() @@ -443,7 +451,7 @@ def run(self): break except Exception as e: - pass + log.debug(e) finally: # wait, checking for halt event before more processing self._halt_event.wait(self.DISPATCH_INTERVAL) @@ -732,8 +740,8 @@ def log(cls, group, name, properties=None, log_once=False, bundle=None): from sgtk.platform.util import current_bundle bundle = current_bundle() - except: - pass + except Exception as e: + log.debug(e) if not bundle: # Still no bundle? Fallback to engine @@ -742,9 +750,8 @@ def log(cls, group, name, properties=None, log_once=False, bundle=None): from ..platform.engine import current_engine bundle = current_engine() - except: - # Bailing out trying to guess bundle - pass + except Exception as e: + log.debug(e) if bundle: # Add base properties to specified properties (if any) diff --git a/python/tank/util/pyside2_patcher.py b/python/tank/util/pyside2_patcher.py index c20df2bcb2..489098243a 100644 --- a/python/tank/util/pyside2_patcher.py +++ b/python/tank/util/pyside2_patcher.py @@ -21,8 +21,9 @@ import subprocess import webbrowser -from .. import constants +from .. import constants, LogManager from .platforms import is_linux, is_macos, is_windows +log = LogManager.get_logger(__name__) class PySide2Patcher(object): @@ -326,7 +327,8 @@ def openUrl(cls, url): # returns False or raises some error. try: return webbrowser.open_new_tab(url.toString().encode("utf-8")) - except: + except Exception as e: + log.debug(e) return False @classmethod diff --git a/python/tank/util/qt_importer.py b/python/tank/util/qt_importer.py index 11df865e52..b6b333cdbc 100644 --- a/python/tank/util/qt_importer.py +++ b/python/tank/util/qt_importer.py @@ -437,14 +437,16 @@ def _import_modules(self, interface_version_requested): pyside2 = self._import_pyside2_as_pyside() logger.debug("Imported PySide2 as PySide.") return pyside2 - except ImportError: + except ImportError as e: + logger.debug("Cant import PySide2 as PySide: %s" % e) pass elif interface_version_requested == self.QT5: try: pyside2 = self._import_pyside2() logger.debug("Imported PySide2.") return pyside2 - except ImportError: + except ImportError as e: + logger.debug("Cant import PySide2: %s" % e) pass elif interface_version_requested == self.QT6: # TODO migrate qt base from Qt4 interface to Qt6 will require patching Qt5 as Qt6 @@ -459,7 +461,8 @@ def _import_modules(self, interface_version_requested): pyside = self._import_pyside() logger.debug("Imported PySide1.") return pyside - except ImportError: + except ImportError as e: + logger.debug("Cant import PySide1: %s" % e) pass # Now try PyQt4 @@ -468,7 +471,8 @@ def _import_modules(self, interface_version_requested): pyqt = self._import_pyqt4() logger.debug("Imported PyQt4.") return pyqt - except ImportError: + except ImportError as e: + logger.debug("Cant import PyQt4: %s" % e) pass logger.debug("No Qt matching that interface was found.") diff --git a/python/tank/util/shotgun/publish_util.py b/python/tank/util/shotgun/publish_util.py index af3576b480..ed324f168c 100644 --- a/python/tank/util/shotgun/publish_util.py +++ b/python/tank/util/shotgun/publish_util.py @@ -52,7 +52,8 @@ def get_entity_type_display_name(tk, entity_type_code): try: if entity_type_code in schema_data: display_name = schema_data[entity_type_code]["name"]["value"] - except: + except Exception as e: + log.exception("Cant get entity type display name %s" % entity_type_code) pass return display_name diff --git a/setup.py b/setup.py index 4c98f175b9..84af847532 100644 --- a/setup.py +++ b/setup.py @@ -35,17 +35,15 @@ def get_version(): ["git", "describe", "--abbrev=0"], universal_newlines=True ).rstrip() return version_git - except: - # Blindly ignore problems, git might be not available, or the user could - # be installing from zip archive, etc... - pass - - # If everything fails, return a sensible string highlighting that the version - # couldn't be extracted. If a version is not specified in `setup`, 0.0.0 - # will be used by default, it seems better to have an explicit keyword for - # this case, following TK "dev" locator pattern and the convention described here: - # http://peak.telecommunity.com/DevCenter/setuptools#specifying-your-project-s-version - return "dev" + except Exception as e: + print(e) + print("Fallback on `dev` version") + # If everything fails, return a sensible string highlighting that the version + # couldn't be extracted. If a version is not specified in `setup`, 0.0.0 + # will be used by default, it seems better to have an explicit keyword for + # this case, following TK "dev" locator pattern and the convention described here: + # http://peak.telecommunity.com/DevCenter/setuptools#specifying-your-project-s-version + return "dev" # Retrieve long description and licence from external files diff --git a/tests/platform_tests/test_application.py b/tests/platform_tests/test_application.py index 91234ac7b5..b19da07481 100644 --- a/tests/platform_tests/test_application.py +++ b/tests/platform_tests/test_application.py @@ -21,9 +21,8 @@ from tank_test.tank_test_base import * import tank from tank.errors import TankError, TankHookMethodDoesNotExistError -from tank.platform import application, constants, validation +from tank.platform import application, validation from tank.template import Template -from tank.deploy import descriptor from tank_vendor import six from tank_vendor.six import StringIO diff --git a/tests/python/tank_test/tank_test_base.py b/tests/python/tank_test/tank_test_base.py index 3c5fe33311..34cf790440 100644 --- a/tests/python/tank_test/tank_test_base.py +++ b/tests/python/tank_test/tank_test_base.py @@ -94,9 +94,8 @@ def _is_git_missing(): try: sgtk.util.process.subprocess_check_output(["git", "--version"]) git_missing = False - except Exception: - # no git! - pass + except Exception as e: + print("Git not found: %s" % e) return git_missing From 5cd34480980be655be6efcc319c4b3d8cd282da3 Mon Sep 17 00:00:00 2001 From: Mathieu <923463-mathbou@users.noreply.gitlab.com> Date: Wed, 1 Feb 2023 00:53:36 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20QtImporter=20raise?= =?UTF-8?q?=20importError=20instead=20of=20returning=20none?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interactive_authentication.py | 7 +++--- python/tank/authentication/invoker.py | 3 ++- .../core/username_password_dialog.py | 10 ++++---- .../tank/authentication/ui_authentication.py | 3 ++- python/tank/bootstrap/async_bootstrap.py | 13 +++++----- python/tank/platform/engine.py | 24 ++++++++++++------- python/tank/util/qt_importer.py | 23 +++++++++--------- 7 files changed, 47 insertions(+), 36 deletions(-) diff --git a/python/tank/authentication/interactive_authentication.py b/python/tank/authentication/interactive_authentication.py index 3207fd9233..8ff9406d5f 100644 --- a/python/tank/authentication/interactive_authentication.py +++ b/python/tank/authentication/interactive_authentication.py @@ -41,13 +41,14 @@ # something usually done by the Toolkit. The worry is that the import may fail # in the context of a DCC, but occur too early for the Toolkit logging to be # fully in place to record it. +logger = LogManager.get_logger(__name__) + try: from .ui.qt_abstraction import QtGui -except Exception: +except ImportError as e: + logger.debug("Cant import QtGui: %s" %e) QtGui = None -logger = LogManager.get_logger(__name__) - ############################################################################################### # internal classes and methods diff --git a/python/tank/authentication/invoker.py b/python/tank/authentication/invoker.py index 09b2f85323..de24b1ca6f 100644 --- a/python/tank/authentication/invoker.py +++ b/python/tank/authentication/invoker.py @@ -30,7 +30,8 @@ # fully in place to record it. try: from .ui.qt_abstraction import QtCore, QtGui -except Exception: +except ImportError as e: + logger.debug("Cant import QtCore/QtGui: %s" % e) QtCore, QtGui = None, None diff --git a/python/tank/authentication/sso_saml2/core/username_password_dialog.py b/python/tank/authentication/sso_saml2/core/username_password_dialog.py index ef2856942f..86029e0f99 100644 --- a/python/tank/authentication/sso_saml2/core/username_password_dialog.py +++ b/python/tank/authentication/sso_saml2/core/username_password_dialog.py @@ -13,12 +13,10 @@ from __future__ import print_function -# pylint: disable=import-error -from ...ui.qt_abstraction import QtCore, QtGui - -# No point in proceeding if QtGui is None. -if QtGui is None: - raise ImportError("Unable to import QtGui") +try: + from ...ui.qt_abstraction import QtCore, QtGui +except ImportError: + raise class UsernamePasswordDialog(QtGui.QDialog): diff --git a/python/tank/authentication/ui_authentication.py b/python/tank/authentication/ui_authentication.py index 486262e6a3..6f68effffc 100644 --- a/python/tank/authentication/ui_authentication.py +++ b/python/tank/authentication/ui_authentication.py @@ -32,7 +32,8 @@ # fully in place to record it. try: from .login_dialog import LoginDialog -except Exception: +except ImportError as e: + logger.debug("Cant import LoginDialog: %s" % e) LoginDialog = None diff --git a/python/tank/bootstrap/async_bootstrap.py b/python/tank/bootstrap/async_bootstrap.py index 39abebb9d6..22bd12377d 100644 --- a/python/tank/bootstrap/async_bootstrap.py +++ b/python/tank/bootstrap/async_bootstrap.py @@ -11,12 +11,13 @@ # Import Qt without having to worry about the version to use. from ..util.qt_importer import QtImporter -importer = QtImporter() -QtCore = importer.QtCore -QtGui = importer.QtGui -if QtCore is None: - # Raise an exception when Qt is not available. - raise ImportError +try: + importer = QtImporter() +except ImportError: + raise +else: + QtCore = importer.QtCore + QtGui = importer.QtGui class AsyncBootstrapWrapper(QtCore.QObject): diff --git a/python/tank/platform/engine.py b/python/tank/platform/engine.py index c413b834eb..7703cc8891 100644 --- a/python/tank/platform/engine.py +++ b/python/tank/platform/engine.py @@ -188,7 +188,11 @@ def __init__(self, tk, context, engine_instance_name, env): # Update the authentication module to use the engine's Qt. # @todo: can this import be untangled? Code references internal part of the auth module - from ..authentication.ui import qt_abstraction + try: + from ..authentication.ui import qt_abstraction + except ImportError: + class qt_abstraction: + pass qt_abstraction.QtCore = qt.QtCore qt_abstraction.QtGui = qt.QtGui @@ -416,13 +420,13 @@ def __show_busy(self, title, details): from .qt.busy_dialog import BusyDialog from .qt import QtGui, QtCore - except: + except ImportError as e: # QT import failed. This may be because someone has upgraded the core # to the latest but are still running a earlier version of the # Shotgun or Shell engine where the self.has_ui method is not # correctly implemented. In that case, absorb the error and # emit a log message - self.log_info("[%s] %s" % (title, details)) + self.log_info("[%s] %s: %s" % (title, details, e)) else: # our qt import worked! @@ -2152,7 +2156,7 @@ def _define_qt_base(self): :returns: dict """ - base = {"qt_core": None, "qt_gui": None, "dialog_base": None} + base = {"qt_core": None, "qt_gui": None, "dialog_base": None, "wrapper": None} try: importer = QtImporter() base["qt_core"] = importer.QtCore @@ -2162,11 +2166,11 @@ def _define_qt_base(self): else: base["dialog_base"] = None base["wrapper"] = importer.binding - except: + except ImportError: - self.log_exception( + self.log_error( "Default engine QT definition failed to find QT. " - "This may need to be subclassed." + "This may need to be subclassed" ) return base @@ -2182,7 +2186,11 @@ def __define_qt5_base(self): :returns: A dictionary with all the modules, __version__ and __name__. """ - return QtImporter(interface_version_requested=QtImporter.QT5).base + try: + return QtImporter(interface_version_requested=QtImporter.QT5).base + except ImportError as e: + self.log_debug(e) + return {} def __define_qt6_base(self): """ diff --git a/python/tank/util/qt_importer.py b/python/tank/util/qt_importer.py index b6b333cdbc..1c9579c769 100644 --- a/python/tank/util/qt_importer.py +++ b/python/tank/util/qt_importer.py @@ -26,7 +26,7 @@ class QtImporter(object): .. code-block:: python try: importer = QtImporter() - except Exception as e: + except ImportError as e: print "Couldn't import a Qt Wrapper: " % (e,) else: importer.QtGui.QApplication([]) @@ -42,13 +42,16 @@ def __init__(self, interface_version_requested=QT4): :param interface_version_request: Indicates which version of the Qt API is requested. """ - ( - self._binding_name, - self._binding_version, - self._binding, - self._modules, - self._qt_version_tuple, - ) = self._import_modules(interface_version_requested) + try: + ( + self._binding_name, + self._binding_version, + self._binding, + self._modules, + self._qt_version_tuple, + ) = self._import_modules(interface_version_requested) + except ImportError: + raise @property def QtCore(self): @@ -475,6 +478,4 @@ def _import_modules(self, interface_version_requested): logger.debug("Cant import PyQt4: %s" % e) pass - logger.debug("No Qt matching that interface was found.") - - return (None, None, None, None, None) + raise ImportError("No Qt matching that interface was found.") From 48c9d05305173733680c4c7b2dbcf9206b5e8f2b Mon Sep 17 00:00:00 2001 From: Mathieu <923463-mathbou@users.noreply.gitlab.com> Date: Sun, 27 Aug 2023 16:51:08 +0200 Subject: [PATCH 3/3] =?UTF-8?q?=20=F0=9F=8E=A8=20black?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/tank/api.py | 2 +- python/tank/authentication/interactive_authentication.py | 4 ++-- python/tank/commands/misc.py | 4 +++- python/tank/hook.py | 3 ++- python/tank/pipelineconfig_utils.py | 4 +++- python/tank/platform/engine.py | 1 + python/tank/util/metrics.py | 2 -- python/tank/util/pyside2_patcher.py | 1 + python/tank/util/shotgun/publish_util.py | 2 +- 9 files changed, 14 insertions(+), 9 deletions(-) diff --git a/python/tank/api.py b/python/tank/api.py index 429eacbca5..be15353846 100644 --- a/python/tank/api.py +++ b/python/tank/api.py @@ -283,7 +283,7 @@ def documentation_url(self): if data == "": data = None except Exception as e: - log.debug("Cant get documentation url: %s" %e) + log.debug("Cant get documentation url: %s" % e) data = None return data diff --git a/python/tank/authentication/interactive_authentication.py b/python/tank/authentication/interactive_authentication.py index 8ff9406d5f..1fcaa4ecd8 100644 --- a/python/tank/authentication/interactive_authentication.py +++ b/python/tank/authentication/interactive_authentication.py @@ -46,7 +46,7 @@ try: from .ui.qt_abstraction import QtGui except ImportError as e: - logger.debug("Cant import QtGui: %s" %e) + logger.debug("Cant import QtGui: %s" % e) QtGui = None @@ -70,7 +70,7 @@ def _get_current_os_user(): pwd_entry = pwd.getpwuid(os.geteuid()) return pwd_entry[0] except Exception as e: - logger.debug("Cant get current user: %s" %e) + logger.debug("Cant get current user: %s" % e) return None diff --git a/python/tank/commands/misc.py b/python/tank/commands/misc.py index 4208d44df5..e685437932 100644 --- a/python/tank/commands/misc.py +++ b/python/tank/commands/misc.py @@ -71,7 +71,9 @@ def _run(self, log): try: os.remove(full_path) except OSError as e: - log.warning("Could not delete cache file '%s'! // %s" % (full_path, e)) + log.warning( + "Could not delete cache file '%s'! // %s" % (full_path, e) + ) log.info("The SG menu cache has been cleared.") diff --git a/python/tank/hook.py b/python/tank/hook.py index 01d6f5f66e..dcf68b8a88 100644 --- a/python/tank/hook.py +++ b/python/tank/hook.py @@ -450,7 +450,8 @@ def some_method(self): except Exception as e: raise TankError( "Cannot load framework %s for %r - it does not have a " - "valid engine property! // %s" % (framework_instance_name, self.__parent, e) + "valid engine property! // %s" + % (framework_instance_name, self.__parent, e) ) return framework.load_framework( diff --git a/python/tank/pipelineconfig_utils.py b/python/tank/pipelineconfig_utils.py index 6838fc4b6b..c99da2ec4c 100644 --- a/python/tank/pipelineconfig_utils.py +++ b/python/tank/pipelineconfig_utils.py @@ -260,7 +260,9 @@ def get_core_path_for_config(pipeline_config_path): studio_folder = os.path.normpath(studio_folder) return studio_folder except Exception: - logger.debug("Cant get core path for config %s" % pipeline_config_path, exc_info=True) + logger.debug( + "Cant get core path for config %s" % pipeline_config_path, exc_info=True + ) return None diff --git a/python/tank/platform/engine.py b/python/tank/platform/engine.py index 7703cc8891..5d8aeae2eb 100644 --- a/python/tank/platform/engine.py +++ b/python/tank/platform/engine.py @@ -191,6 +191,7 @@ def __init__(self, tk, context, engine_instance_name, env): try: from ..authentication.ui import qt_abstraction except ImportError: + class qt_abstraction: pass diff --git a/python/tank/util/metrics.py b/python/tank/util/metrics.py index 403ef65563..165ae08db4 100644 --- a/python/tank/util/metrics.py +++ b/python/tank/util/metrics.py @@ -108,7 +108,6 @@ def get_linux_version(cls): major_version_str = re.findall(r"\d*", raw_version_str)[0] os_version = "%s %s" % (distribution, major_version_str) - except Exception: log.debug("Cant get Linux version.", exc_info=True) pass @@ -176,7 +175,6 @@ def get_platform_info(cls): else: os_info["OS"] = "Unsupported system: (%s)" % (system) - except Exception: # On any exception we fallback to default value log.debug("Cant get platform info.", exc_info=True) diff --git a/python/tank/util/pyside2_patcher.py b/python/tank/util/pyside2_patcher.py index 489098243a..c2ac5fc133 100644 --- a/python/tank/util/pyside2_patcher.py +++ b/python/tank/util/pyside2_patcher.py @@ -23,6 +23,7 @@ from .. import constants, LogManager from .platforms import is_linux, is_macos, is_windows + log = LogManager.get_logger(__name__) diff --git a/python/tank/util/shotgun/publish_util.py b/python/tank/util/shotgun/publish_util.py index ed324f168c..8336520c5c 100644 --- a/python/tank/util/shotgun/publish_util.py +++ b/python/tank/util/shotgun/publish_util.py @@ -52,7 +52,7 @@ def get_entity_type_display_name(tk, entity_type_code): try: if entity_type_code in schema_data: display_name = schema_data[entity_type_code]["name"]["value"] - except Exception as e: + except Exception: log.exception("Cant get entity type display name %s" % entity_type_code) pass