From 708443a22e67a1744cc84915cc387f00c9a6b689 Mon Sep 17 00:00:00 2001 From: Josselin Date: Wed, 19 Feb 2020 20:16:58 +0100 Subject: [PATCH] Improve error handling (fix #45, fix #62) --- crytic_compile/platform/brownie.py | 6 ++-- crytic_compile/platform/dapp.py | 7 +++-- crytic_compile/platform/embark.py | 20 ++++++++----- crytic_compile/platform/etherlime.py | 5 +++- crytic_compile/platform/solc.py | 28 +++++++++++-------- crytic_compile/platform/solc_standard_json.py | 17 ++++++----- crytic_compile/platform/truffle.py | 7 ++++- crytic_compile/platform/vyper.py | 4 +-- crytic_compile/platform/waffle.py | 19 +++++++++---- 9 files changed, 74 insertions(+), 39 deletions(-) diff --git a/crytic_compile/platform/brownie.py b/crytic_compile/platform/brownie.py index 8d663746..3c16c6da 100755 --- a/crytic_compile/platform/brownie.py +++ b/crytic_compile/platform/brownie.py @@ -37,8 +37,10 @@ def compile(crytic_compile: "CryticCompile", target: str, **kwargs: Dict): if not brownie_ignore_compile: cmd = base_cmd + ["compile"] - - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target) + try: + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target) + except OSError as e: + raise InvalidCompilation(e) stdout_bytes, stderr_bytes = process.communicate() stdout, stderr = ( diff --git a/crytic_compile/platform/dapp.py b/crytic_compile/platform/dapp.py index 5ddc59a5..88c428f5 100755 --- a/crytic_compile/platform/dapp.py +++ b/crytic_compile/platform/dapp.py @@ -22,12 +22,10 @@ convert_filename, ) - # Handle cycle if TYPE_CHECKING: from crytic_compile import CryticCompile - LOGGER = logging.getLogger("CryticCompile") @@ -150,7 +148,10 @@ def _run_dapp(target: str): """ cmd = ["dapp", "build"] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target) + try: + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target) + except OSError as e: + raise InvalidCompilation(e) _, _ = process.communicate() diff --git a/crytic_compile/platform/embark.py b/crytic_compile/platform/embark.py index a1f9c75e..f358e82a 100755 --- a/crytic_compile/platform/embark.py +++ b/crytic_compile/platform/embark.py @@ -45,7 +45,10 @@ def compile(crytic_compile: "CryticCompile", target: str, **kwargs: str): embark_json["plugins"][plugin_name] = {"flags": ""} write_embark_json = True if write_embark_json: - process = subprocess.Popen(["npm", "install", plugin_name], cwd=target) + try: + process = subprocess.Popen(["npm", "install", plugin_name], cwd=target) + except OSError as e: + raise InvalidCompilation(e) _, stderr = process.communicate() with open(os.path.join(target, "embark.json"), "w", encoding="utf8") as outfile: json.dump(embark_json, outfile, indent=2) @@ -59,12 +62,15 @@ def compile(crytic_compile: "CryticCompile", target: str, **kwargs: str): ) if not embark_ignore_compile: - process = subprocess.Popen( - ["embark", "build", "--contracts"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - cwd=target, - ) + try: + process = subprocess.Popen( + ["embark", "build", "--contracts"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=target, + ) + except OSError as e: + raise InvalidCompilation(e) stdout, stderr = process.communicate() LOGGER.info("%s\n", stdout.decode()) if stderr: diff --git a/crytic_compile/platform/etherlime.py b/crytic_compile/platform/etherlime.py index d158814b..8cee6db7 100755 --- a/crytic_compile/platform/etherlime.py +++ b/crytic_compile/platform/etherlime.py @@ -45,7 +45,10 @@ def compile(crytic_compile: "CryticCompile", target: str, **kwargs: str): if compile_arguments: cmd += compile_arguments.split(" ") - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + try: + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except OSError as e: + raise InvalidCompilation(e) stdout_bytes, stderr_bytes = process.communicate() stdout, stderr = ( diff --git a/crytic_compile/platform/solc.py b/crytic_compile/platform/solc.py index 39447e6d..4c9258b2 100644 --- a/crytic_compile/platform/solc.py +++ b/crytic_compile/platform/solc.py @@ -201,11 +201,15 @@ def get_version(solc: str) -> str: :return: """ cmd = [solc, "--version"] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + try: + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except OSError as e: + raise InvalidCompilation(e) stdout_bytes, _ = process.communicate() stdout = stdout_bytes.decode() # convert bytestrings to unicode strings version = re.findall(r"\d+\.\d+\.\d+", stdout) - assert len(version) != 0 + if len(version) == 0: + raise InvalidCompilation(f'Solidity version not found: {stdout}') return version[0] @@ -290,15 +294,17 @@ def _run_solc( relative_filepath = relative_filepath[len(working_dir) + 1 :] cmd += ["--allow-paths", ".", relative_filepath] - - if env: - process = subprocess.Popen( - cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, **additional_kwargs - ) - else: - process = subprocess.Popen( - cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **additional_kwargs - ) + try: + if env: + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, **additional_kwargs + ) + else: + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **additional_kwargs + ) + except OSError as e: + raise InvalidCompilation(e) stdout, stderr = process.communicate() stdout, stderr = (stdout.decode(), stderr.decode()) # convert bytestrings to unicode strings diff --git a/crytic_compile/platform/solc_standard_json.py b/crytic_compile/platform/solc_standard_json.py index 1eeeaf57..625020ed 100644 --- a/crytic_compile/platform/solc_standard_json.py +++ b/crytic_compile/platform/solc_standard_json.py @@ -214,13 +214,16 @@ def _run_solc_standard_json( cmd = [solc, "--standard-json", "--allow-paths", "."] additional_kwargs = {"cwd": working_dir} if working_dir else {} - process = subprocess.Popen( - cmd, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - **additional_kwargs, - ) + try: + process = subprocess.Popen( + cmd, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + **additional_kwargs, + ) + except OSError as e: + raise InvalidCompilation(e) stdout, stderr = process.communicate(json.dumps(solc_input).encode("utf-8")) stdout, stderr = (stdout.decode(), stderr.decode()) # convert bytestrings to unicode strings diff --git a/crytic_compile/platform/truffle.py b/crytic_compile/platform/truffle.py index 535b33f9..688e61d8 100755 --- a/crytic_compile/platform/truffle.py +++ b/crytic_compile/platform/truffle.py @@ -233,9 +233,14 @@ def _get_version_from_config(target: str) -> Optional[Tuple[str, str]]: def _get_version(truffle_call, cwd): cmd = truffle_call + ["version"] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + try: + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + except OSError as e: + raise InvalidCompilation(f"Truffle failed: {e}") stdout, _ = process.communicate() stdout = stdout.decode() # convert bytestrings to unicode strings + if not stdout: + raise InvalidCompilation(f"Truffle failed to run: 'truffle version'") stdout = stdout.split("\n") for line in stdout: if "Solidity" in line: diff --git a/crytic_compile/platform/vyper.py b/crytic_compile/platform/vyper.py index 6d99e50b..31f39de6 100644 --- a/crytic_compile/platform/vyper.py +++ b/crytic_compile/platform/vyper.py @@ -81,8 +81,8 @@ def _run_vyper(filename: str, vyper: str, env: Dict = None, working_dir: str = N process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, **additional_kwargs ) - except Exception as exception: - raise InvalidCompilation(exception) + except OSError as e: + raise InvalidCompilation(e) stdout, stderr = process.communicate() diff --git a/crytic_compile/platform/waffle.py b/crytic_compile/platform/waffle.py index a03366ae..f944804d 100755 --- a/crytic_compile/platform/waffle.py +++ b/crytic_compile/platform/waffle.py @@ -118,9 +118,12 @@ def compile(crytic_compile: "CryticCompile", target: str, **kwargs: str): LOGGER.info("Temporary file created: %s", file_desc.name) LOGGER.info("'%s running", " ".join(cmd)) - process = subprocess.Popen( - cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target - ) + try: + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target + ) + except OSError as e: + raise InvalidCompilation(e) stdout, stderr = process.communicate() stdout, stderr = ( @@ -224,7 +227,10 @@ def _get_version(compiler: str, cwd: str, config=None) -> str: elif compiler == "native": cmd = ["solc", "--version"] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + try: + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + except OSError as e: + raise InvalidCompilation(e) stdout_bytes, _ = process.communicate() stdout = stdout_bytes.decode() # convert bytestrings to unicode strings stdout = stdout.split("\n") @@ -234,7 +240,10 @@ def _get_version(compiler: str, cwd: str, config=None) -> str: elif compiler == "solc-js": cmd = ["solcjs", "--version"] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + try: + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + except OSError as e: + raise InvalidCompilation(e) stdout_bytes, _ = process.communicate() stdout = stdout_bytes.decode() # convert bytestrings to unicode strings version = re.findall(r"\d+\.\d+\.\d+", stdout)[0]