diff --git a/example/tdd_discovery.dart b/example/tdd_discovery.dart new file mode 100644 index 00000000..50e50415 --- /dev/null +++ b/example/tdd_discovery.dart @@ -0,0 +1,30 @@ +// Copyright 2024 Contributors to the Eclipse Foundation. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// SPDX-License-Identifier: BSD-3-Clause + +// ignore_for_file: avoid_print + +import "package:dart_wot/binding_http.dart"; +import "package:dart_wot/core.dart"; + +Future main() async { + final servient = Servient.create( + clientFactories: [ + HttpClientFactory(), + ], + ); + final wot = await servient.start(); + + final url = Uri.parse("http://plugfest.thingweb.io:8081"); + print("Requesting TD from $url ..."); + final thingDiscoveryProcess = await wot.exploreDirectory(url); + + thingDiscoveryProcess.listen( + (thingDescription) => print(thingDescription.title), + onError: print, + ); + + await servient.shutdown(); +} diff --git a/lib/src/core/definitions/extensions/json_parser.dart b/lib/src/core/definitions/extensions/json_parser.dart index 94b338c7..9077829b 100644 --- a/lib/src/core/definitions/extensions/json_parser.dart +++ b/lib/src/core/definitions/extensions/json_parser.dart @@ -61,7 +61,9 @@ extension ParseField on Map { return {} as T; } - throw FormatException("Expected $T, got ${fieldValue.runtimeType}"); + throw FormatException( + "Expected $T, got ${fieldValue.runtimeType} for field $name", + ); } /// Parses a single field with a given [name] as a [Uri]. diff --git a/lib/src/core/implementation/servient.dart b/lib/src/core/implementation/servient.dart index 75435b7b..bda5c3f4 100644 --- a/lib/src/core/implementation/servient.dart +++ b/lib/src/core/implementation/servient.dart @@ -4,6 +4,8 @@ // // SPDX-License-Identifier: BSD-3-Clause +import "dart:developer"; + import "package:meta/meta.dart"; import "package:uuid/uuid.dart"; @@ -379,6 +381,21 @@ class InternalServient implements Servient { return ThingDescription.fromJson(dataSchemaValue.value); } + Stream _processThingDescriptions( + List rawThingDescriptions, + ) async* { + for (final rawThingDescription in rawThingDescriptions) { + if (rawThingDescription is Map) { + try { + yield rawThingDescription.toThingDescription(); + } on Exception catch (e) { + log(e.toString()); + yield* Stream.error(e); + } + } + } + } + /// Retrieves [ThingDescription] from a Thing Description Directory (TDD). /// /// This method expects the TDD's Thing Description to be located under the @@ -435,9 +452,8 @@ class InternalServient implements Servient { ); } - final thingDescriptionStream = Stream.fromIterable( - rawThingDescriptions.whereType>(), - ).map((rawThingDescription) => rawThingDescription.toThingDescription()); + final thingDescriptionStream = + _processThingDescriptions(rawThingDescriptions); return ThingDiscoveryProcess(thingDescriptionStream, thingFilter); } diff --git a/lib/src/core/implementation/thing_discovery.dart b/lib/src/core/implementation/thing_discovery.dart index dbf6e780..741a07d8 100644 --- a/lib/src/core/implementation/thing_discovery.dart +++ b/lib/src/core/implementation/thing_discovery.dart @@ -485,11 +485,11 @@ class ThingDiscoveryProcess extends Stream }) { final streamSubscription = _thingDescriptionStream.listen( onData, - onError: (error, stackTrace) { + onError: (error) { if (error is Exception) { _error = error; // ignore: avoid_dynamic_calls - onError?.call(error, stackTrace); + onError?.call(error); } }, onDone: () { diff --git a/test/core/discovery_test.dart b/test/core/discovery_test.dart index 068a6a1a..c46d94c1 100644 --- a/test/core/discovery_test.dart +++ b/test/core/discovery_test.dart @@ -352,7 +352,7 @@ void main() { (event) { counter++; }, - onError: (error, stackTrace) async {}, + onError: (error) async {}, onDone: () { expect(counter, 0); expect(thingDiscoveryProcess.done, true);