Skip to content

Commit 5ada3d1

Browse files
committed
json-file
1 parent ccdf7ed commit 5ada3d1

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

src/azure-cli-core/azure/cli/core/commands/validators.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from azure.cli.core.profiles import ResourceType
1111

1212
from knack.log import get_logger
13+
from knack.util import CLIError
1314
from knack.validators import DefaultStr, DefaultInt # pylint: disable=unused-import
1415

1516
logger = get_logger(__name__)
@@ -84,12 +85,26 @@ def get_default_location_from_resource_group(cmd, namespace):
8485
def validate_file_or_dict(string):
8586
import os
8687
string = os.path.expanduser(string)
87-
if os.path.exists(string):
88-
from azure.cli.core.util import get_file_json
89-
return get_file_json(string)
90-
91-
from azure.cli.core.util import shell_safe_json_parse
92-
return shell_safe_json_parse(string)
88+
try:
89+
if os.path.exists(string):
90+
from azure.cli.core.util import get_file_json
91+
# Failure point 1: 'string' is a valid file path, but the file contains invalid JSON string
92+
# ex has no recommendation
93+
return get_file_json(string)
94+
95+
from azure.cli.core.util import shell_safe_json_parse
96+
# Failure point 2:
97+
# - 'string' is a non-existing file path
98+
# - 'string' is an invalid JSON string
99+
# ex has recommendations for shell interpretation
100+
return shell_safe_json_parse(string)
101+
except CLIError as ex:
102+
from azure.cli.core.azclierror import InvalidArgumentValueError
103+
new_ex = InvalidArgumentValueError(ex, recommendation="Please provide a valid JSON file path or JSON string.")
104+
# Preserve the recommendation
105+
if hasattr(ex, "recommendations"):
106+
new_ex.set_recommendation(ex.recommendations)
107+
raise new_ex from ex
93108

94109

95110
def validate_parameter_set(namespace, required, forbidden, dest_to_options=None, description=None):

src/azure-cli-core/azure/cli/core/util.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,8 @@ def get_file_json(file_path, throw_on_empty=True, preserve_order=False):
523523
try:
524524
return shell_safe_json_parse(content, preserve_order)
525525
except CLIError as ex:
526-
raise CLIError("Failed to parse {} with exception:\n {}".format(file_path, ex))
526+
# Reading file bypasses shell interpretation, so we discard the recommendation for shell quoting.
527+
raise CLIError("Failed to parse file '{}' with exception:\n{}".format(file_path, ex))
527528

528529

529530
def read_file_content(file_path, allow_binary=False):
@@ -563,12 +564,13 @@ def shell_safe_json_parse(json_or_dict_string, preserve_order=False, strict=True
563564
except Exception as ex:
564565
logger.debug(ex) # log the exception which could be a python dict parsing error.
565566

566-
# Echo the JSON received by CLI
567-
msg = "Failed to parse JSON: {}\nError detail: {}".format(json_or_dict_string, json_ex)
567+
# Echo the string received by CLI. Because the user may intend to provide a file path, we don't decisively
568+
# say it is a JSON string.
569+
msg = "Failed to parse string as JSON:\n{}\nError detail: {}".format(json_or_dict_string, json_ex)
568570

569571
# Recommendation for all shells
570572
from azure.cli.core.azclierror import InvalidArgumentValueError
571-
recommendation = "The JSON may have been parsed by the shell. See " \
573+
recommendation = "The provided JSON string may have been parsed by the shell. See " \
572574
"https://docs.microsoft.com/cli/azure/use-cli-effectively#use-quotation-marks-in-arguments"
573575

574576
# Recommendation especially for PowerShell

0 commit comments

Comments
 (0)