Skip to content

Commit 22ad919

Browse files
Add in custom exception classes for Parameter errors. (#2) (#195)
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> Co-authored-by: Chris Lalancette <clalancette@gmail.com>
1 parent 5134c54 commit 22ad919

File tree

8 files changed

+172
-53
lines changed

8 files changed

+172
-53
lines changed

rcljava/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ set(${PROJECT_NAME}_sources
138138
"src/main/java/org/ros2/rcljava/parameters/client/AsyncParametersClientImpl.java"
139139
"src/main/java/org/ros2/rcljava/parameters/client/SyncParametersClient.java"
140140
"src/main/java/org/ros2/rcljava/parameters/client/SyncParametersClientImpl.java"
141+
"src/main/java/org/ros2/rcljava/parameters/InvalidParametersException.java"
142+
"src/main/java/org/ros2/rcljava/parameters/InvalidParameterValueException.java"
143+
"src/main/java/org/ros2/rcljava/parameters/ParameterAlreadyDeclaredException.java"
141144
"src/main/java/org/ros2/rcljava/parameters/ParameterCallback.java"
142145
"src/main/java/org/ros2/rcljava/parameters/ParameterNames.java"
146+
"src/main/java/org/ros2/rcljava/parameters/ParameterNotDeclaredException.java"
143147
"src/main/java/org/ros2/rcljava/parameters/ParameterType.java"
144148
"src/main/java/org/ros2/rcljava/parameters/ParameterVariant.java"
145149
"src/main/java/org/ros2/rcljava/parameters/service/ParameterService.java"

rcljava/src/main/java/org/ros2/rcljava/node/Node.java

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,6 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
177177

178178
String getName();
179179

180-
/*
181-
* TODO(clalancette): The parameter APIs below all tend to throw
182-
* IllegalArgumentException on failure. We should instead add in custom
183-
* exception classes to make it easier for the caller to determine the
184-
* cause of the exception.
185-
*/
186-
187180
/**
188181
* Declare and initialize a parameter, return the effective value.
189182
*
@@ -208,18 +201,17 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
208201
* This method, if successful, will result in any callback registered with
209202
* addOnSetParametersCallback to be called.
210203
* If that callback prevents the initial value for the parameter from being
211-
* set then an IllegalArgumentException is thrown.
204+
* set then an InvalidParameterValueException is thrown.
212205
*
213206
* The returned reference will remain valid until the parameter is
214207
* undeclared.
215208
*
216209
* @param parameter The parameter to declare.
217210
* @param descriptor The descriptor to declare.
218211
* @return The parameter.
219-
* @throws IllegalArgumentException if parameter has already been declared.
220-
* @throws rclcpp::exceptions::InvalidParametersException if a parameter
221-
* name is invalid.
222-
* @throws IllegalArgumentException if initial value fails to be set.
212+
* @throws InvalidParametersException if the parameter name is invalid.
213+
* @throws ParameterAlreadyDeclaredException if parameter has already been declared.
214+
* @throws InvalidParameterValueException if initial value fails to be set.
223215
*/
224216
ParameterVariant declareParameter(ParameterVariant parameter, rcl_interfaces.msg.ParameterDescriptor descriptor);
225217

@@ -235,15 +227,17 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
235227
* This method, if successful, will result in any callback registered with
236228
* addOnSetParametersCallback to be called, once for each parameter.
237229
* If that callback prevents the initial value for any parameter from being
238-
* set then an IllegalArgumentException is thrown.
230+
* set then an InvalidParameterValueException is thrown.
239231
*
240232
* @param parameters The parameters to set.
241233
* @param descriptors The descriptors to set.
242234
* @return The list of parameters that were declared.
243235
* @throws IllegalArgumentException if the parameters list and descriptors
244236
* list are not the same length.
245-
* @throws IllegalArgumentException if any parameter in the list has already
237+
* @throws InvalidParametersException if any of the parameter names is invalid.
238+
* @throws ParameterAlreadyDeclaredException if any parameter in the list has already
246239
* been declared.
240+
* @throws InvalidParameterValueException if any of the initial values fail to be set.
247241
*/
248242
List<ParameterVariant> declareParameters(List<ParameterVariant> parameters, List<rcl_interfaces.msg.ParameterDescriptor> descriptors);
249243

@@ -254,7 +248,7 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
254248
* addOnSetParametersCallback to be called.
255249
*
256250
* @param name The name of the parameter to be undeclared.
257-
* @throws IllegalArgumentException if the parameter
251+
* @throws ParameterNotDeclaredException if the parameter
258252
* has not been declared.
259253
*/
260254
void undeclareParameter(String name);
@@ -270,17 +264,17 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
270264
/**
271265
* Return a list of parameters by the given list of parameter names.
272266
*
273-
* This method will throw an IllegalArgumentException if any of the requested
267+
* This method will throw a ParameterNotDeclaredException if any of the requested
274268
* parameters have not been declared and undeclared parameters are not
275269
* allowed.
276270
*
277271
* If undeclared parameters are allowed and the parameter has not been
278-
* declared, then the returned rclcpp::Parameter will be default initialized
272+
* declared, then the returned ParameterVariant will be default initialized
279273
* and therefore have the type ParameterType::PARAMETER_NOT_SET.
280274
*
281275
* @param names The names of the parameters to be retrieved.
282276
* @return The parameters that were retrieved.
283-
* @throws IllegalArgumentException if any of the parameters have not been
277+
* @throws ParameterNotDeclaredException if any of the parameters have not been
284278
* declared and undeclared parameters are not allowed.
285279
*/
286280
List<ParameterVariant> getParameters(List<String> names);
@@ -292,15 +286,15 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
292286
*
293287
* @param name The names of the parameters to be retrieved.
294288
* @return The parameter that was retrieved.
295-
* @throws IllegalArgumentException if the parameter has not been declared
289+
* @throws ParameterNotDeclaredException if the parameter has not been declared
296290
* and undeclared parameters are not allowed.
297291
*/
298292
ParameterVariant getParameter(String name);
299293

300294
/**
301295
* Return the named parameter value, or the "alternativeValue" if not set.
302296
*
303-
* This method will not throw IllegalArgumentException if a parameter is
297+
* This method will not throw ParameterNotDeclaredException if a parameter is
304298
* not declared.
305299
* Instead, it will return the alternativeValue.
306300
*
@@ -336,7 +330,7 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
336330
* Set the given parameter and then return result of the set action.
337331
*
338332
* If the parameter has not been declared and undeclared parameters are not
339-
* allowed, this function will throw an IllegalArgumentException.
333+
* allowed, this function will throw a ParameterNotDeclaredException.
340334
*
341335
* If undeclared parameters are allowed, then the parameter is implicitly
342336
* declared with the default parameter meta data before being set.
@@ -354,7 +348,8 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
354348
*
355349
* @param parameter The parameter to be set.
356350
* @return The result of the set action.
357-
* @throws IllegalArgumentException if the parameter
351+
* @throws InvalidParametersException if parameter name is invalid.
352+
* @throws ParameterNotDeclaredException if the parameter
358353
* has not been declared and undeclared parameters are not allowed.
359354
*/
360355
rcl_interfaces.msg.SetParametersResult setParameter(ParameterVariant parameter);
@@ -367,7 +362,7 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
367362
*
368363
* Like setParameter, if any of the parameters to be set have not first been
369364
* declared, and undeclared parameters are not allowed (the default), then
370-
* this method will throw an IllegalArgumentException.
365+
* this method will throw a ParameterNotDeclaredException.
371366
*
372367
* If setting a parameter fails due to not being declared, then the
373368
* parameters which have already been set will stay set, and no attempt will
@@ -389,7 +384,8 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
389384
*
390385
* @param parameters The list of parameters to be set.
391386
* @return The results for each set action as a list.
392-
* @throws IllegalArgumentException if any parameter has not been declared
387+
* @throws InvalidParametersException if any parameter name is invalid.
388+
* @throws ParameterNotDeclaredException if any parameter has not been declared
393389
* and undeclared parameters are not allowed.
394390
*/
395391
List<rcl_interfaces.msg.SetParametersResult> setParameters(List<ParameterVariant> parameters);
@@ -400,8 +396,8 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
400396
* In contrast to setParameters, either all of the parameters are set or none
401397
* of them are set.
402398
*
403-
* Like setParameter and setParameters, this method may throw an
404-
* IllegalArgumentException if any of the parameters to be set have not first
399+
* Like setParameter and setParameters, this method will throw a
400+
* ParameterNotDeclaredException if any of the parameters to be set have not first
405401
* been declared.
406402
* If the exception is thrown then none of the parameters will have been set.
407403
*
@@ -419,7 +415,8 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
419415
*
420416
* @param parameters The list of parameters to be set.
421417
* @return The aggregate result of setting all the parameters atomically.
422-
* @throws IllegalArgumentException if any parameter has not been declared
418+
* @throws InvalidParametersException if any parameter name is invalid.
419+
* @throws ParameterNotDeclaredException if any parameter has not been declared
423420
* and undeclared parameters are not allowed.
424421
*/
425422
rcl_interfaces.msg.SetParametersResult setParametersAtomically(List<ParameterVariant> parameters);
@@ -467,23 +464,23 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
467464
/**
468465
* Return the parameter descriptor for the given parameter name.
469466
*
470-
* This method will throw an IllegalArgumentException if the requested
467+
* This method will throw an ParameterNotDeclaredException if the requested
471468
* parameter has not been declared and undeclared parameters are not allowed.
472469
*
473470
* If undeclared parameters are allowed, then a default initialized
474471
* descriptor will be returned.
475472
*
476473
* @param name The name of the parameter to describe.
477474
* @return The descriptor for the given parameter name.
478-
* @throws IllegalArgumentException if the parameter has not been declared
475+
* @throws ParameterNotDeclaredException if the parameter has not been declared
479476
* and undeclared parameters are not allowed.
480477
*/
481478
rcl_interfaces.msg.ParameterDescriptor describeParameter(String name);
482479

483480
/**
484481
* Return a List of parameter descriptors, one for each of the given names.
485482
*
486-
* This method will throw an IllegalArgumentException if any of the requested
483+
* This method will throw an ParameterNotDeclaredException if any of the requested
487484
* parameters have not been declared and undeclared parameters are not allowed.
488485
*
489486
* If undeclared parameters are allowed, then a default initialized
@@ -493,23 +490,23 @@ <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
493490
*
494491
* @param names The list of parameter names to describe.
495492
* @return A list of parameter descriptors, one for each parameter given.
496-
* @throws IllegalArgumentException if any of the parameters have not been
493+
* @throws ParameterNotDeclaredException if any of the parameters have not been
497494
* declared and undeclared parameters are not allowed.
498495
*/
499496
List<rcl_interfaces.msg.ParameterDescriptor> describeParameters(List<String> names);
500497

501498
/**
502499
* Return a list of parameter types, one for each of the given names.
503500
*
504-
* This method will throw an IllegalArgumentException if any of the requested
501+
* This method will throw an ParameterNotDeclaredException if any of the requested
505502
* parameters have not been declared and undeclared parameters are not allowed.
506503
*
507504
* If undeclared parameters are allowed, then the default type
508-
* rclcpp::ParameterType::PARAMETER_NOT_SET will be returned.
505+
* ParameterType::PARAMETER_NOT_SET will be returned.
509506
*
510507
* @param names The list of parameter names to get the types.
511508
* @return A list of parameter types, one for each parameter given.
512-
* @throws IllegalArgumentException if any of the parameters have not been
509+
* @throws ParameterNotDeclaredException if any of the parameters have not been
513510
* declared and undeclared parameters are not allowed.
514511
*/
515512
List<ParameterType> getParameterTypes(List<String> names);

rcljava/src/main/java/org/ros2/rcljava/node/NodeImpl.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
import org.ros2.rcljava.interfaces.Disposable;
2828
import org.ros2.rcljava.interfaces.MessageDefinition;
2929
import org.ros2.rcljava.interfaces.ServiceDefinition;
30+
import org.ros2.rcljava.parameters.InvalidParametersException;
31+
import org.ros2.rcljava.parameters.InvalidParameterValueException;
32+
import org.ros2.rcljava.parameters.ParameterAlreadyDeclaredException;
3033
import org.ros2.rcljava.parameters.ParameterCallback;
34+
import org.ros2.rcljava.parameters.ParameterNotDeclaredException;
3135
import org.ros2.rcljava.parameters.ParameterType;
3236
import org.ros2.rcljava.parameters.ParameterVariant;
3337
import org.ros2.rcljava.publisher.Publisher;
@@ -429,11 +433,17 @@ public List<ParameterVariant> declareParameters(List<ParameterVariant> parameter
429433
throw new IllegalArgumentException("Parameters length must be equal to descriptors length");
430434
}
431435

436+
for (ParameterVariant parameter : parameters) {
437+
if (parameter.getName().length() == 0) {
438+
throw new InvalidParametersException("Parameter name must not be empty");
439+
}
440+
}
441+
432442
synchronized (parameterCallbacksMutex) {
433443
for (ParameterCallback cb : this.parameterCallbacks) {
434444
rcl_interfaces.msg.SetParametersResult result = cb.callback(parameters);
435445
if (!result.getSuccessful()) {
436-
throw new IllegalArgumentException("Failed to declare parameters; rejected by callback");
446+
throw new InvalidParameterValueException(String.format("Parameters were rejected by callback: %s", result.getReason()));
437447
}
438448
}
439449
}
@@ -447,7 +457,7 @@ public List<ParameterVariant> declareParameters(List<ParameterVariant> parameter
447457
rcl_interfaces.msg.ParameterDescriptor descriptor = itpd.next();
448458

449459
if (this.parameters.containsKey(parameter.getName())) {
450-
throw new IllegalArgumentException(String.format("Parameter '%s' is already declared", parameter.getName()));
460+
throw new ParameterAlreadyDeclaredException(String.format("Parameter '%s' is already declared", parameter.getName()));
451461
}
452462

453463
ParameterAndDescriptor pandd = new ParameterAndDescriptor();
@@ -465,7 +475,7 @@ public List<ParameterVariant> declareParameters(List<ParameterVariant> parameter
465475
public void undeclareParameter(String name) {
466476
synchronized (parametersMutex) {
467477
if (!this.parameters.containsKey(name)) {
468-
throw new IllegalArgumentException(String.format("Parameter '%s' is not declared", name));
478+
throw new ParameterNotDeclaredException(String.format("Parameter '%s' is not declared", name));
469479
}
470480

471481
this.parameters.remove(name);
@@ -488,7 +498,7 @@ public List<ParameterVariant> getParameters(List<String> names) {
488498
} else if (this.allowUndeclaredParameters) {
489499
results.add(new ParameterVariant(name));
490500
} else {
491-
throw new IllegalArgumentException(String.format("Parameter '%s' is not declared", name));
501+
throw new ParameterNotDeclaredException(String.format("Parameter '%s' is not declared", name));
492502
}
493503
}
494504
}
@@ -534,6 +544,12 @@ private rcl_interfaces.msg.SetParametersResult internalSetParametersAtomically(
534544
List<ParameterVariant> parameters) {
535545
rcl_interfaces.msg.SetParametersResult result = new rcl_interfaces.msg.SetParametersResult();
536546

547+
for (ParameterVariant parameter : parameters) {
548+
if (parameter.getName().length() == 0) {
549+
throw new InvalidParametersException("Parameter name must not be empty");
550+
}
551+
}
552+
537553
synchronized (parameterCallbacksMutex) {
538554
for (ParameterCallback cb : this.parameterCallbacks) {
539555
result = cb.callback(parameters);
@@ -561,7 +577,7 @@ private rcl_interfaces.msg.SetParametersResult internalSetParametersAtomically(
561577
if (this.allowUndeclaredParameters) {
562578
parametersToDeclare.add(parameter.getName());
563579
} else {
564-
throw new IllegalArgumentException(String.format("Parameter '%s' is not declared", parameter.getName()));
580+
throw new ParameterNotDeclaredException(String.format("Parameter '%s' is not declared", parameter.getName()));
565581
}
566582
}
567583
}
@@ -654,7 +670,7 @@ public List<rcl_interfaces.msg.ParameterDescriptor> describeParameters(
654670
} else if (this.allowUndeclaredParameters) {
655671
results.add(new rcl_interfaces.msg.ParameterDescriptor().setName(name));
656672
} else {
657-
throw new IllegalArgumentException(String.format("Parameter '%s' is not declared", name));
673+
throw new ParameterNotDeclaredException(String.format("Parameter '%s' is not declared", name));
658674
}
659675
}
660676
}
@@ -672,7 +688,7 @@ public List<ParameterType> getParameterTypes(List<String> names) {
672688
} else if (this.allowUndeclaredParameters) {
673689
results.add(ParameterType.fromByte(rcl_interfaces.msg.ParameterType.PARAMETER_NOT_SET));
674690
} else {
675-
throw new IllegalArgumentException(String.format("Parameter '%s' is not declared", name));
691+
throw new ParameterNotDeclaredException(String.format("Parameter '%s' is not declared", name));
676692
}
677693
}
678694
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Copyright 2020 Open Source Robotics Foundation, Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
package org.ros2.rcljava.parameters;
17+
18+
public class InvalidParameterValueException extends RuntimeException {
19+
public InvalidParameterValueException(String message) {
20+
super(message);
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Copyright 2020 Open Source Robotics Foundation, Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
package org.ros2.rcljava.parameters;
17+
18+
public class InvalidParametersException extends RuntimeException {
19+
public InvalidParametersException(String message) {
20+
super(message);
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Copyright 2020 Open Source Robotics Foundation, Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
package org.ros2.rcljava.parameters;
17+
18+
public class ParameterAlreadyDeclaredException extends RuntimeException {
19+
public ParameterAlreadyDeclaredException(String message) {
20+
super(message);
21+
}
22+
}

0 commit comments

Comments
 (0)