Skip to content

Commit b6f187a

Browse files
authored
More Helpful Error Messages (#275)
* More Helpful Error Messages Signed-off-by: David V. Lu <[email protected]> * Linting Signed-off-by: David V. Lu <[email protected]>
1 parent 20aef20 commit b6f187a

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

launch_ros/launch_ros/utilities/evaluate_parameters.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,17 @@ def check_sequence_type_is_allowed(sequence):
7070
if isinstance(value[0], Substitution):
7171
# Value is a list of substitutions, so perform them to make a string
7272
evaluated_value = perform_substitutions(context, list(value))
73-
yaml_evaluated_value = yaml.safe_load(evaluated_value)
74-
if yaml_evaluated_value is None:
75-
yaml_evaluated_value = ''
73+
74+
try:
75+
yaml_evaluated_value = yaml.safe_load(evaluated_value)
76+
except yaml.YAMLError:
77+
raise TypeError(
78+
'Unable to parse the value of parameter {} as yaml. '
79+
'If the parameter is meant to be a string, try wrapping it in '
80+
'launch_ros.parameter_descriptions.ParameterValue'
81+
'(value, value_type=str)'.format(evaluated_name)
82+
)
83+
7684
if type(yaml_evaluated_value) in (bool, int, float, str, bytes):
7785
evaluated_value = yaml_evaluated_value
7886
elif isinstance(yaml_evaluated_value, Sequence):
@@ -87,9 +95,10 @@ def check_sequence_type_is_allowed(sequence):
8795
else:
8896
raise TypeError(
8997
'Allowed value types are bytes, bool, int, float, str, Sequence[bool]'
90-
', Sequence[int], Sequence[float], Sequence[str]. Got {}.'.format(
91-
type(yaml_evaluated_value)
92-
)
98+
', Sequence[int], Sequence[float], Sequence[str]. Got {}.'
99+
'If the parameter is meant to be a string, try wrapping it in '
100+
'launch_ros.parameter_descriptions.ParameterValue'
101+
'(value, value_type=str)'.format(type(yaml_evaluated_value))
93102
)
94103
elif isinstance(value[0], Sequence):
95104
# Value is an array of a list of substitutions

test_launch_ros/test/test_launch_ros/utilities/test_normalize_parameters.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
"""Tests for the normalizing parameters utility."""
1616

1717
import pathlib
18+
from typing import List
1819

1920
from launch import LaunchContext
2021
from launch.substitutions import TextSubstitution
2122

23+
from launch_ros.parameter_descriptions import ParameterValue
2224
from launch_ros.utilities import evaluate_parameters
2325
from launch_ros.utilities import normalize_parameters
2426

@@ -339,3 +341,58 @@ def test_unallowed_yaml_types_in_substitutions():
339341
norm = normalize_parameters(orig)
340342
evaluate_parameters(LaunchContext(), norm)
341343
assert 'Expected a non-empty sequence' in str(exc.value)
344+
345+
with pytest.raises(TypeError) as exc:
346+
orig = [{'foo': 1, 'fiz': TextSubstitution(text='Text That : Cannot Be Parsed As : Yaml')}]
347+
norm = normalize_parameters(orig)
348+
evaluate_parameters(LaunchContext(), norm)
349+
assert 'Unable to parse' in str(exc.value)
350+
351+
352+
def test_unallowed_yaml_types_as_strings():
353+
# All the tests from test_unallowed_yaml_types_in_substitutions
354+
# but coerced to the proper type with ParameterValue
355+
orig = [{'foo': 1, 'fiz': ParameterValue(TextSubstitution(text="{'asd': 3}"), value_type=str)}]
356+
norm = normalize_parameters(orig)
357+
expected = ({'foo': 1, 'fiz': "{'asd': 3}"},)
358+
assert evaluate_parameters(LaunchContext(), norm) == expected
359+
360+
orig = [{'foo': 1, 'fiz': ParameterValue(TextSubstitution(text='[1, 2.0, 3]'),
361+
value_type=str)}]
362+
norm = normalize_parameters(orig)
363+
evaluate_parameters(LaunchContext(), norm)
364+
expected = ({'foo': 1, 'fiz': '[1, 2.0, 3]'},)
365+
assert evaluate_parameters(LaunchContext(), norm) == expected
366+
367+
orig = [{'foo': 1, 'fiz': ParameterValue(TextSubstitution(text='[[2, 3], [2, 3], [2, 3]]'),
368+
value_type=str)}]
369+
norm = normalize_parameters(orig)
370+
evaluate_parameters(LaunchContext(), norm)
371+
expected = ({'foo': 1, 'fiz': '[[2, 3], [2, 3], [2, 3]]'},)
372+
assert evaluate_parameters(LaunchContext(), norm) == expected
373+
374+
orig = [{'foo': 1, 'fiz': ParameterValue(TextSubstitution(text='[]'), value_type=str)}]
375+
norm = normalize_parameters(orig)
376+
evaluate_parameters(LaunchContext(), norm)
377+
expected = ({'foo': 1, 'fiz': '[]'},)
378+
assert evaluate_parameters(LaunchContext(), norm) == expected
379+
380+
orig = [{
381+
'foo': 1,
382+
'fiz': ParameterValue([
383+
[TextSubstitution(text="['asd', 'bsd']")],
384+
[TextSubstitution(text="['asd', 'csd']")]
385+
], value_type=List[str])
386+
}]
387+
norm = normalize_parameters(orig)
388+
evaluate_parameters(LaunchContext(), norm)
389+
expected = ({'foo': 1, 'fiz': ["['asd', 'bsd']", "['asd', 'csd']"]},)
390+
assert evaluate_parameters(LaunchContext(), norm) == expected
391+
392+
orig = [{'foo': 1,
393+
'fiz': ParameterValue(TextSubstitution(text='Text That : Cannot Be Parsed As : Yaml'),
394+
value_type=str)}]
395+
norm = normalize_parameters(orig)
396+
evaluate_parameters(LaunchContext(), norm)
397+
expected = ({'foo': 1, 'fiz': 'Text That : Cannot Be Parsed As : Yaml'},)
398+
assert evaluate_parameters(LaunchContext(), norm) == expected

0 commit comments

Comments
 (0)