Skip to content

Commit 7ca6356

Browse files
committed
Refactor error handling in SCM and add error handling test.
This commit includes a new test in test_scm.py to verify the correct formatting and raising of subprocess errors in the SCM module. Additionally, the subprocess error handling has been refactored in the SCM module to include a new method, format_and_raise_error, for improved code readability and reusability.
1 parent 58aca6d commit 7ca6356

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

bumpversion/scm.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,22 @@ def commit(cls, message: str, current_version: str, new_version: str, extra_args
7373
cmd = [*cls._COMMIT_COMMAND, f.name, *extra_args]
7474
subprocess.run(cmd, env=env, capture_output=True, check=True) # noqa: S603
7575
except (subprocess.CalledProcessError, TypeError) as exc: # pragma: no-coverage
76-
if isinstance(exc, TypeError):
77-
err_msg = f"Failed to run {cls._COMMIT_COMMAND}: {exc}"
78-
else:
79-
output = "\n".join([x for x in [exc.stdout, exc.stderr] if x])
80-
err_msg = f"Failed to run {exc.cmd}: return code {exc.returncode}, output: {output}"
81-
logger.exception(err_msg)
82-
raise BumpVersionError(err_msg) from exc
76+
cls.format_and_raise_error(exc)
8377
finally:
8478
os.unlink(f.name)
8579

80+
@classmethod
81+
def format_and_raise_error(cls, exc: Union[TypeError, subprocess.CalledProcessError]) -> None:
82+
"""Format the error message from an exception and re-raise it as a BumpVersionError."""
83+
if isinstance(exc, TypeError):
84+
err_msg = f"Failed to run {cls._COMMIT_COMMAND}: {exc}"
85+
else:
86+
output = "\n".join([x for x in [exc.stdout.decode("utf8"), exc.stderr.decode("utf8")] if x])
87+
cmd = " ".join(exc.cmd)
88+
err_msg = f"Failed to run `{cmd}`: return code {exc.returncode}, output: {output}"
89+
logger.exception(err_msg)
90+
raise BumpVersionError(err_msg) from exc
91+
8692
@classmethod
8793
def is_usable(cls) -> bool:
8894
"""Is the VCS implementation usable."""

tests/test_scm.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,25 @@
77
from pytest import param, LogCaptureFixture
88

99
from bumpversion import scm
10-
from bumpversion.exceptions import DirtyWorkingDirectoryError
10+
from bumpversion.exceptions import DirtyWorkingDirectoryError, BumpVersionError
1111
from bumpversion.ui import setup_logging
1212
from tests.conftest import get_config_data, inside_dir
1313

1414

15+
def test_format_and_raise_error(git_repo: Path) -> None:
16+
"""The output formatting from called process error string works as expected."""
17+
with inside_dir(git_repo):
18+
try:
19+
subprocess.run(["git", "add", "newfile.txt"], capture_output=True, check=True)
20+
except subprocess.CalledProcessError as e:
21+
with pytest.raises(BumpVersionError) as bump_error:
22+
scm.Git.format_and_raise_error(e)
23+
assert bump_error.value.message == (
24+
"Failed to run `git add newfile.txt`: return code 128, output: "
25+
"fatal: pathspec 'newfile.txt' did not match any files\n"
26+
)
27+
28+
1529
def test_git_is_usable(git_repo: Path) -> None:
1630
"""Should return true if git is available, and it is a git repo."""
1731
with inside_dir(git_repo):

0 commit comments

Comments
 (0)