diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 39890d9649..bf452c60a8 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -21,7 +21,6 @@ from urllib.parse import urlencode from urllib.parse import urlsplit from urllib.parse import urlunsplit - except ImportError: # Python 2 from cgi import parse_qs # type: ignore @@ -30,6 +29,13 @@ from urlparse import urlsplit # type: ignore from urlparse import urlunsplit # type: ignore +try: + # Python 3 + FileNotFoundError +except NameError: + # Python 2 + FileNotFoundError = IOError + try: # Python 3.11 from builtins import BaseExceptionGroup @@ -97,8 +103,8 @@ def _get_debug_hub(): def get_git_revision(): # type: () -> Optional[str] - with open(os.path.devnull, "w+") as null: - try: + try: + with open(os.path.devnull, "w+") as null: revision = ( subprocess.Popen( ["git", "rev-parse", "HEAD"], @@ -110,8 +116,8 @@ def get_git_revision(): .strip() .decode("utf-8") ) - except (OSError, IOError): - return None + except (OSError, IOError, FileNotFoundError): + return None return revision diff --git a/tests/test_utils.py b/tests/test_utils.py index efbfa7504b..f8cc7874cd 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -6,6 +6,7 @@ Components, Dsn, get_error_message, + get_git_revision, is_valid_sample_rate, logger, match_regex_list, @@ -25,6 +26,13 @@ except ImportError: import mock # python < 3.3 +try: + # Python 3 + FileNotFoundError +except NameError: + # Python 2 + FileNotFoundError = IOError + def _normalize_distribution_name(name): # type: (str) -> str @@ -557,3 +565,17 @@ def test_installed_modules_caching(): _get_installed_modules() mock_generate_installed_modules.assert_not_called() + + +def test_devnull_inaccessible(): + with mock.patch("sentry_sdk.utils.open", side_effect=OSError("oh no")): + revision = get_git_revision() + + assert revision is None + + +def test_devnull_not_found(): + with mock.patch("sentry_sdk.utils.open", side_effect=FileNotFoundError("oh no")): + revision = get_git_revision() + + assert revision is None