diff --git a/build/fbcode_builder/getdeps.py b/build/fbcode_builder/getdeps.py index cf76609ad..e669b56d3 100755 --- a/build/fbcode_builder/getdeps.py +++ b/build/fbcode_builder/getdeps.py @@ -16,6 +16,7 @@ import subprocess import sys from getdeps.buildopts import setup_build_options +from getdeps.errors import TransientFailure from getdeps.load import load_project, manifests_in_dependency_order from getdeps.manifest import ManifestParser from getdeps.platform import HostType, context_from_host_tuple @@ -407,7 +408,14 @@ def main(): return 0 try: return args.func(args) - except subprocess.CalledProcessError: + except TransientFailure as exc: + print("TransientFailure: %s" % str(exc)) + # This return code is treated as a retryable transient infrastructure + # error by Facebook's internal CI, rather than eg: a build or code + # related error that needs to be fixed before progress can be made. + return 128 + except subprocess.CalledProcessError as exc: + print("%s" % str(exc), file=sys.stderr) print("!! Failed", file=sys.stderr) return 1 diff --git a/build/fbcode_builder/getdeps/errors.py b/build/fbcode_builder/getdeps/errors.py new file mode 100644 index 000000000..419a67503 --- /dev/null +++ b/build/fbcode_builder/getdeps/errors.py @@ -0,0 +1,16 @@ +# Copyright (c) 2019-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +from __future__ import absolute_import, division, print_function, unicode_literals + + +class TransientFailure(Exception): + """ Raising this error causes getdeps to return with an error code + that Sandcastle will consider to be a retryable transient + infrastructure error """ + + pass diff --git a/build/fbcode_builder/getdeps/fetcher.py b/build/fbcode_builder/getdeps/fetcher.py index ea2cf2fd2..dc54ef43a 100644 --- a/build/fbcode_builder/getdeps/fetcher.py +++ b/build/fbcode_builder/getdeps/fetcher.py @@ -21,6 +21,7 @@ import zipfile from .copytree import prefetch_dir_if_eden from .envfuncs import Env +from .errors import TransientFailure from .platform import is_windows from .runcmd import run_cmd @@ -548,7 +549,13 @@ def download_url_to_file_with_progress(url, file_name): progress = Progress() start = time.time() - (_filename, headers) = urlretrieve(url, file_name, reporthook=progress.progress) + try: + (_filename, headers) = urlretrieve(url, file_name, reporthook=progress.progress) + except OSError as exc: + raise TransientFailure( + "Failed to download %s to %s: %s" % (url, file_name, str(exc)) + ) + end = time.time() sys.stdout.write(" [Complete in %f seconds]\n" % (end - start)) sys.stdout.flush()