From f17c35d9f8449894d9315de22bc73895fefcdd90 Mon Sep 17 00:00:00 2001 From: tdstein Date: Fri, 21 Feb 2025 09:58:05 -0500 Subject: [PATCH 1/3] fix: display system error message when rsconnect.environment inspection fails --- rsconnect/bundle.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/rsconnect/bundle.py b/rsconnect/bundle.py index e9790e84..3852ec13 100644 --- a/rsconnect/bundle.py +++ b/rsconnect/bundle.py @@ -1716,16 +1716,29 @@ def inspect_environment( flags: list[str] = [] if force_generate: flags.append("f") + args = [python, "-m", "rsconnect.environment"] - if len(flags) > 0: + if flags: args.append("-" + "".join(flags)) args.append(directory) try: - environment_json = check_output(args, universal_newlines=True) + environment_json = check_output(args, text=True) except subprocess.CalledProcessError as e: - raise RSConnectException("Error inspecting environment: %s" % e.output) - return MakeEnvironment(**json.loads(environment_json)) + raise RSConnectException(f"Error inspecting environment (subprocess failed): {e.output}") from e + + try: + environment_data = json.loads(environment_json) + except json.JSONDecodeError as e: + raise RSConnectException(f"Error parsing environment JSON: {str(e)}") from e + + try: + return MakeEnvironment(**environment_data) + except TypeError as e: + system_error_message = environment_data.get("error") + if system_error_message: + raise RSConnectException(f"Error creating environment: {system_error_message}") from e + raise RSConnectException(f"Error constructing environment object: {str(e)}") from e def get_python_env_info( From 176f1bf9256483c364f4a3aa53161375b84e887d Mon Sep 17 00:00:00 2001 From: tdstein Date: Fri, 21 Feb 2025 10:54:52 -0500 Subject: [PATCH 2/3] test: check TypeError is caught when invalid command passed --- rsconnect/bundle.py | 8 ++++---- tests/test_bundle.py | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/rsconnect/bundle.py b/rsconnect/bundle.py index 3852ec13..df9ba659 100644 --- a/rsconnect/bundle.py +++ b/rsconnect/bundle.py @@ -1724,13 +1724,13 @@ def inspect_environment( try: environment_json = check_output(args, text=True) - except subprocess.CalledProcessError as e: - raise RSConnectException(f"Error inspecting environment (subprocess failed): {e.output}") from e + except Exception as e: + raise RSConnectException("Error inspecting environment (subprocess failed)") from e try: environment_data = json.loads(environment_json) except json.JSONDecodeError as e: - raise RSConnectException(f"Error parsing environment JSON: {str(e)}") from e + raise RSConnectException("Error parsing environment JSON") from e try: return MakeEnvironment(**environment_data) @@ -1738,7 +1738,7 @@ def inspect_environment( system_error_message = environment_data.get("error") if system_error_message: raise RSConnectException(f"Error creating environment: {system_error_message}") from e - raise RSConnectException(f"Error constructing environment object: {str(e)}") from e + raise RSConnectException("Error constructing environment object") from e def get_python_env_info( diff --git a/tests/test_bundle.py b/tests/test_bundle.py index 7a2c31aa..bc07e13e 100644 --- a/tests/test_bundle.py +++ b/tests/test_bundle.py @@ -1212,6 +1212,14 @@ def test_inspect_environment(self): assert environment is not None assert environment.python != "" + def test_inspect_environment_catches_type_error(self): + with pytest.raises(RSConnectException) as exec_info: + inspect_environment(sys.executable, None) # type: ignore + + assert isinstance(exec_info.value, RSConnectException) + assert isinstance(exec_info.value.__cause__, TypeError) + + @pytest.mark.parametrize( ( From 9e41dcc192be5ec8c9d834bad1ac0bf3504ad1d6 Mon Sep 17 00:00:00 2001 From: tdstein Date: Fri, 21 Feb 2025 10:56:26 -0500 Subject: [PATCH 3/3] style: formatting --- tests/test_bundle.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_bundle.py b/tests/test_bundle.py index bc07e13e..30e727c2 100644 --- a/tests/test_bundle.py +++ b/tests/test_bundle.py @@ -1214,13 +1214,12 @@ def test_inspect_environment(self): def test_inspect_environment_catches_type_error(self): with pytest.raises(RSConnectException) as exec_info: - inspect_environment(sys.executable, None) # type: ignore + inspect_environment(sys.executable, None) # type: ignore assert isinstance(exec_info.value, RSConnectException) assert isinstance(exec_info.value.__cause__, TypeError) - @pytest.mark.parametrize( ( "file_name",