diff --git a/readthedocs/projects/exceptions.py b/readthedocs/projects/exceptions.py index bf68193715a..489ab6a9ede 100644 --- a/readthedocs/projects/exceptions.py +++ b/readthedocs/projects/exceptions.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Project exceptions.""" @@ -47,7 +46,16 @@ class RepositoryError(BuildUserError): FAILED_TO_CHECKOUT = _('Failed to checkout revision: {}') - def get_default_message(self): + GENERIC_ERROR = _( + "There was a problem cloning your repository. " + "Please check the command output for more information.", + ) + + @property + def CLONE_ERROR(self): # noqa: N802 if settings.ALLOW_PRIVATE_REPOS: return self.PRIVATE_ALLOWED return self.PRIVATE_NOT_ALLOWED + + def get_default_message(self): + return self.GENERIC_ERROR diff --git a/readthedocs/vcs_support/backends/bzr.py b/readthedocs/vcs_support/backends/bzr.py index b4f73b3be9d..2ccfdd1be8b 100644 --- a/readthedocs/vcs_support/backends/bzr.py +++ b/readthedocs/vcs_support/backends/bzr.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Bazaar-related utilities.""" @@ -36,7 +35,10 @@ def up(self): def clone(self): self.make_clean_working_dir() - self.run('bzr', 'checkout', self.repo_url, '.') + try: + self.run("bzr", "checkout", self.repo_url, ".") + except RepositoryError: + raise RepositoryError(RepositoryError.CLONE_ERROR) @property def tags(self): diff --git a/readthedocs/vcs_support/backends/git.py b/readthedocs/vcs_support/backends/git.py index 2fd0da99f3c..826e7d38211 100644 --- a/readthedocs/vcs_support/backends/git.py +++ b/readthedocs/vcs_support/backends/git.py @@ -1,12 +1,12 @@ """Git-related utilities.""" -import structlog import re import git -from gitdb.util import hex_to_bin +import structlog from django.core.exceptions import ValidationError from git.exc import BadName, InvalidGitRepositoryError, NoSuchPathError +from gitdb.util import hex_to_bin from readthedocs.builds.constants import EXTERNAL from readthedocs.config import ALL @@ -20,7 +20,6 @@ from readthedocs.projects.validators import validate_submodule_url from readthedocs.vcs_support.base import BaseVCS, VCSVersion - log = structlog.get_logger(__name__) @@ -197,8 +196,11 @@ def clone(self): cmd.extend([self.repo_url, '.']) - code, stdout, stderr = self.run(*cmd) - return code, stdout, stderr + try: + code, stdout, stderr = self.run(*cmd) + return code, stdout, stderr + except RepositoryError: + raise RepositoryError(RepositoryError.CLONE_ERROR) @property def lsremote(self): diff --git a/readthedocs/vcs_support/backends/hg.py b/readthedocs/vcs_support/backends/hg.py index 670e1423ee7..e37cb738fe6 100644 --- a/readthedocs/vcs_support/backends/hg.py +++ b/readthedocs/vcs_support/backends/hg.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Mercurial-related utilities.""" from readthedocs.projects.exceptions import RepositoryError @@ -33,8 +32,11 @@ def pull(self): def clone(self): self.make_clean_working_dir() - output = self.run('hg', 'clone', self.repo_url, '.') - return output + try: + output = self.run("hg", "clone", self.repo_url, ".") + return output + except RepositoryError: + raise RepositoryError(RepositoryError.CLONE_ERROR) @property def branches(self): diff --git a/readthedocs/vcs_support/backends/svn.py b/readthedocs/vcs_support/backends/svn.py index 03204ca1d9b..7059451fbcf 100644 --- a/readthedocs/vcs_support/backends/svn.py +++ b/readthedocs/vcs_support/backends/svn.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Subversion-related utilities.""" @@ -63,7 +62,7 @@ def co(self, identifier=None): url = self.repo_url retcode, out, err = self.run('svn', 'checkout', url, '.') if retcode != 0: - raise RepositoryError + raise RepositoryError(RepositoryError.CLONE_ERROR) return retcode, out, err @property diff --git a/readthedocs/vcs_support/base.py b/readthedocs/vcs_support/base.py index 51bd001906d..8e7be0b2627 100644 --- a/readthedocs/vcs_support/base.py +++ b/readthedocs/vcs_support/base.py @@ -1,11 +1,11 @@ """Base classes for VCS backends.""" -import structlog import os import shutil -from readthedocs.doc_builder.exceptions import BuildUserError, BuildCancelled -from readthedocs.projects.exceptions import RepositoryError +import structlog +from readthedocs.doc_builder.exceptions import BuildCancelled, BuildUserError +from readthedocs.projects.exceptions import RepositoryError log = structlog.get_logger(__name__) @@ -108,7 +108,9 @@ def run(self, *cmd, **kwargs): raise BuildCancelled except BuildUserError as e: # Re raise as RepositoryError to handle it properly from outside - raise RepositoryError(str(e)) + if hasattr(e, "message"): + raise RepositoryError(e.message) + raise RepositoryError # Return a tuple to keep compatibility return (build_cmd.exit_code, build_cmd.output, build_cmd.error)