diff --git a/rsconnect/bundle.py b/rsconnect/bundle.py index e9790e84..df9ba659 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) - except subprocess.CalledProcessError as e: - raise RSConnectException("Error inspecting environment: %s" % e.output) - return MakeEnvironment(**json.loads(environment_json)) + environment_json = check_output(args, text=True) + 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("Error parsing environment JSON") 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("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..30e727c2 100644 --- a/tests/test_bundle.py +++ b/tests/test_bundle.py @@ -1212,6 +1212,13 @@ 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( (