diff --git a/lib/src/exceptions.dart b/lib/src/exceptions.dart index a74a66b6846..aa0e1525ac0 100644 --- a/lib/src/exceptions.dart +++ b/lib/src/exceptions.dart @@ -1,3 +1,5 @@ +import '../protos/common/common.dart'; + /// Error thrown with connection is lost class ConnectionLostException implements Exception { final String? message; @@ -17,3 +19,30 @@ class NotLocalAddressException implements Exception { @override String toString() => 'Address not on local network'; } + +class DuplicateResourceException implements Exception { + final ResourceName name; + + const DuplicateResourceException(this.name); + + @override + String toString() => 'Duplicate registration of resource in manager: $name'; +} + +class ResourceNotFoundException implements Exception { + final ResourceName name; + + const ResourceNotFoundException(this.name); + + @override + String toString() => 'Resource not found in manager: $name'; +} + +class MultipleRemoteResourcesSameNameException implements Exception { + final Iterable names; + + const MultipleRemoteResourcesSameNameException(this.names); + + @override + String toString() => 'Multiple remote resources found with the name ${names.first.localName}: $names'; +} diff --git a/lib/src/resource/manager.dart b/lib/src/resource/manager.dart index 36325750665..522c1e396d0 100644 --- a/lib/src/resource/manager.dart +++ b/lib/src/resource/manager.dart @@ -1,5 +1,6 @@ import 'package:protobuf/protobuf.dart'; +import '../exceptions.dart'; import '../gen/common/v1/common.pb.dart'; import 'base.dart'; @@ -12,7 +13,7 @@ class ResourceManager { /// Register a new [Resource] with the manager. void register(ResourceName name, Resource resource) { if (resources.containsKey(name)) { - throw Exception('Duplicate registration of resource in manager'); + throw DuplicateResourceException(name); } final rnWithoutRemote = name.deepCopy() ..remotePath.clear() @@ -34,13 +35,13 @@ class ResourceManager { // that means there are multiple remote resources with this same short name. // Without any means to disambiguate, we should not select any. if (resourceNames.length > 1) { - throw Exception('Multiple remote resources with found with the name ${name.name}: $resourceNames'); + throw MultipleRemoteResourcesSameNameException(resourceNames); } if (resourceNames.length == 1) { resource = resources[resourceNames.first]; } } - if (resource == null) throw Exception('Resource not found in manager'); + if (resource == null) throw ResourceNotFoundException(name); return resource as T; } } diff --git a/test/unit_test/resource/manager_test.dart b/test/unit_test/resource/manager_test.dart index 7e233ca50df..b676a1ac8cb 100644 --- a/test/unit_test/resource/manager_test.dart +++ b/test/unit_test/resource/manager_test.dart @@ -1,5 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:viam_sdk/src/components/sensor/sensor.dart'; +import 'package:viam_sdk/src/exceptions.dart'; import 'package:viam_sdk/src/resource/manager.dart'; import '../components/sensor_test.dart'; @@ -57,6 +58,28 @@ void main() { expect(manager.getResource(Sensor.getResourceName(localName)), localResource); expect(manager.getResource(Sensor.getResourceName(remoteName)), localResource); }); + + test('Multiple Remotes - Same Names', () { + final remoteName = 'my-sensor'; + + final remotePath1 = 'remote2:remote1'; + final fullRemoteName1 = '$remotePath1:$remoteName'; + final remoteRN1 = Sensor.subtype.getResourceName(fullRemoteName1); + final remoteResource1 = FakeSensor(fullRemoteName1); + + final remotePath2 = 'remote4:remote3'; + final fullRemoteName2 = '$remotePath2:$remoteName'; + final remoteRN2 = Sensor.subtype.getResourceName(fullRemoteName2); + final remoteResource2 = FakeSensor(fullRemoteName2); + + final manager = ResourceManager(); + manager.register(remoteRN1, remoteResource1); + manager.register(remoteRN2, remoteResource2); + + // Error when using short name only + expect(() => manager.getResource(Sensor.getResourceName(remoteName)), + throwsA(isA())); + }); }); }); }